You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The library is a lightweight client for the Firebase Web SDK that provides tools for wrangling geolocation data in Firestore. You need a [Firebase project](https://firebase.google.com/docs/storage/web/start) to get started.
24
+
The library is a lightweight extension for the Firebase Web and Admin JavaScript SDKs to provide tools for wrangling geolocation data in Firestore.
28
25
29
-
```ts
26
+
Web:
27
+
28
+
```js
30
29
// Init Firebase
31
-
import*asfirebasefrom'firebase/app';
30
+
importfirebasefrom'firebase/app';
32
31
firebase.initializeApp(yourConfig);
33
32
34
33
// Init GeoFireX
35
-
import*asgeofirexfrom'geofirex';
34
+
importgeofirexfrom'geofirex';
36
35
constgeo=geofirex.init(firebase);
37
36
```
38
37
39
-
### Write Geo Data
38
+
Node.js with the Firebase Admin SDK:
40
39
41
-
Next, add some geolocation data in your database. A `collection` creates a reference to Firestore (just like the SDK), but with some extra geolocation tools. The `point` method returns a class that helps you create geolocation data.
40
+
```js
41
+
constadmin=require('firebase-admin');
42
+
admin.initializeApp();
43
+
44
+
constgeo=require('geofirex').init(admin);
45
+
```
46
+
47
+
With Typescript:
42
48
43
49
```ts
44
-
const cities =geo.collection('cities');
50
+
import*asgeofirexfrom'geofirex';
51
+
const geo =geofirex.init(firebase);
52
+
```
53
+
54
+
### Write Geolocation Data
45
55
46
-
const point =geo.point(40, -119);
56
+
Next, add some geolocation data in your database using the main Firebase SDK. You can add multiple points to a single doc. Calling `geo.point(lat, lng)` creates an object with a [geohash string](https://www.movable-type.co.uk/scripts/geohash.html) and a [Firestore GeoPoint](https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/GeoPoint). Data must be saved in this format to be queried.
Calling `point.data` returns an object that contains a [geohash string](https://www.movable-type.co.uk/scripts/geohash.html) and a [Firestore GeoPoint](https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/GeoPoint). It should look like this in your database. You can name the object whatever you want and even save multiple points on a single document.
Creates reference to a Firestore collection that can be used to make geo-queries and perform writes If you pass an optional Firestore query function, all subsequent geo-queries will be limited to this subset of documents
96
+
Creates reference to a Firestore collection or query that can be used to make geo-queries.
Returns an object with the required geohash format to save to Firestore.
105
126
106
-
Or use one of the client's conveniece methods
107
-
108
-
-`collection.setDoc(id, data)` - Set a document in the collection with an ID.
109
-
-`collection.setPoint(id, field, lat, lng)`- Add a geohash to an existing doc
127
+
Example: `const point = geo.point(38, -119)`
110
128
111
-
#### Read Data
129
+
A point is a plain JS object with two properties.
112
130
113
-
In addition to Geo-Queries, you can also read the collection like you would normally in Firestore, but as an Observable
131
+
-`point.geohash` Returns a geohash string at precision 9
132
+
-`point.geopoint` Returns a Firestore GeoPoint
114
133
115
-
-`collection.data()`- Observable of document data
116
-
-`collection.snapshot()`- Observable of Firestore QuerySnapshot
117
134
118
-
### `point(latitude: number, longitude: number)`
135
+
##Additional Features
119
136
120
-
Returns a GeoFirePoint allowing you to create geohashes, format data, and calculate relative distance/bearing.
137
+
The goal of this package is to facilitate rapid feature development with tools like MapBox, Google Maps, and D3.js. If you have an idea for a useful feature, open an issue.
121
138
122
-
Example: `const point = geo.point(38, -119)`
139
+
### Logging
123
140
124
-
#### Getters
141
+
Each query runs on a set of geohash squares, so you may read more documents than actually exist inside the radius. Use the `log` option to examine the total query size and latency.
125
142
126
-
-`point.hash` Returns a geohash string at precision 9
127
-
-`point.geoPoint` Returns a Firestore GeoPoint
128
-
-`point.geoJSON` Returns data as a GeoJSON `Feature<Point>`
129
-
-`point.coords` Returns coordinates as `[latitude, longitude]`
130
-
-`point.data` Returns data object suitable for saving to the Firestore database
-`point.distance(latitude, longitude)` Haversine distance to a point
135
-
-`point.bearing(latitude, longitude)` Haversine bearing to a point
149
+
### Geo Calculations
136
150
137
-
## :pizza: Additional Features
151
+
Convenience methods for calculating distance and bearing.
138
152
139
-
The goal of this package is to facilitate rapid feature development with tools like MapBox, Google Maps, and D3.js. If you have an idea for a useful feature, open an issue.
A custom RxJS operator that transforms a collection into a [GeoJSON FeatureCollection](https://macwright.org/2015/03/23/geojson-second-bite.html#featurecollection). Very useful for tools like [MapBox](https://blog.mapbox.com/real-time-maps-for-live-events-fad0b334e4e) that can use GeoJSON to update a realtime data source.
144
159
145
160
```ts
146
-
const query =geo.collection('cars').within(...)
161
+
const query =geo.query('cars').within(...)
147
162
148
163
query.pipe( toGeoJSON() )
149
164
@@ -162,29 +177,32 @@ Don't need a realtime stream? Convert any query observable to a promise by wrapp
162
177
import { get } from'geofirex';
163
178
164
179
asyncfunction getCars {
165
-
const query =geo.collection('cars').within(...)
180
+
const query =geo.query('cars').within(...)
166
181
const cars =awaitget(query)
167
182
}
168
183
```
169
184
170
-
## :zap:Tips
185
+
## Tips
171
186
172
-
### Scale to Massive Collections
187
+
### Compound Queries
173
188
174
-
It's possibe to build Firestore collections with billions of documents. One of the main motivations of this project was to make geoqueries possible on a queried subset of data. You can make a regular Firestore query on collection by passing a callback as the second argument, then all geoqueries will scoped these contstraints.
189
+
The only well-supported type of compound query is `where`. A geoquery combines multiple smaller queries into a unified radius, so `limit` and pagination operators will not provide predictable results - a better approach is to search a smaller radius and do your sorting client-side.
175
190
176
-
Note: This query requires a composite index, which you will be prompted to create with an error from Firestore on the first request.
Note: This query requires a composite index, which you will be prompted to create with an error from Firestore on the first request.
204
+
205
+
188
206
### Usage with RxJS < 6.2, or Ionic v3
189
207
190
208
This package requires RxJS 6.2, but you can still use it with older versions without blowing up your app by installing rxjs-compat.
@@ -195,24 +213,11 @@ Example:
195
213
npm i rxjs@latest rxjs-compat
196
214
```
197
215
198
-
### Seeing this error: `DocumentReference.set() called with invalid data`
199
-
200
-
Firestore writes cannot use custom classes, so make sure to call the `data` getter on the point.
201
-
202
-
```ts
203
-
const point =geo.point(40, -50);
204
-
// This is an ERROR
205
-
ref.add({ location: point });
206
-
207
-
// This is GOOD
208
-
ref.add({ location: point.data });
209
-
```
210
-
211
216
### Make Dynamic Queries the RxJS Way
212
217
213
218
```ts
214
219
const radius =newBehaviorSubject(1);
215
-
const cities =geo.collection('cities');
220
+
const cities =geo.query('cities');
216
221
217
222
const points =this.radius.pipe(
218
223
switchMap(rad=> {
@@ -226,4 +231,4 @@ radius.next(23);
226
231
227
232
### Always Order by `[Latitude, Longitude]`
228
233
229
-
The GeoJSON spec formats coords as `[Longitude, Latitude]` to represent an X/Y plane. However, the Firebase GeoPoint uses `[Latitude, Longitude]`. For consistency, this libary will always require you to use the latter format.
234
+
The GeoJSON spec formats coords as `[Longitude, Latitude]` to represent an X/Y plane. However, the Firebase GeoPoint uses `[Latitude, Longitude]`. For consistency, this library always requires to use the latter Firebase-style format.
0 commit comments