MichaelSolati / geofirestore-js

Location-based querying and filtering using Firebase Firestore.
https://geofirestore.com
MIT License
504 stars 58 forks source link

Create record with no coordinates #159

Closed sedestrian closed 4 years ago

sedestrian commented 4 years ago

Hi, I find myself in need to create a document with coordinates temporarily set to null but the library gives me this error

Unhandled error Error: Invalid GeoFirestore document: could not find GeoPoint at findCoordinates (/srv/node_modules/geofirestore/dist/index.cjs.js:331:15) at encodeSetDocument (/srv/node_modules/geofirestore/dist/index.cjs.js:259:26) at GeoDocumentReference.set (/srv/node_modules/geofirestore/dist/index.cjs.js:1028:35) at Promise (/srv/lib/index.js:382:17) at new Promise (<anonymous>) at /srv/lib/index.js:381:16 at Generator.next (<anonymous>) at /srv/lib/index.js:8:71 at new Promise (<anonymous>) at __awaiter (/srv/lib/index.js:4:12)

Is there a way to do this?

ahsath commented 4 years ago

Maybe getting the aproximate coordinates through IP (if not asking the client for it) and store those?

MichaelSolati commented 4 years ago

Hey @sedestrian, for the point of geofirestore it wouldn't make sense to create an entry without a geopoint. The best course of action would be to create a document using Firestore, and then update the document later.

In geofirestore v3.4.x and above it would look like this...

import * as firebase from 'firebase/app';
import 'firebase/firestore';
import { GeoFirestore, GeoDocumentReference } from 'geofirestore';

// Initialize the Firebase SDK
firebase.initializeApp({
  // ...
});

// Create a GeoFirestore reference
const geofirestore = new GeoFirestore(firebase.firestore());
const geocollection = geofirestore.collection('collection');

(async () => {
  // Create document without coordinates
  const doc = await geocollection.native.add({
    name: 'Geofirestore',
    score: 100
  });

  // Do some stuff, get coordinates

  // Create GeoDoc from original Doc
  const geoDoc = new GeoDocumentReference(doc);

  // Update doc with coordinates
  geoDoc.set({
    ...(await doc.get()).data(),
    coordinates: new firebase.firestore.GeoPoint(lat, lng)
  });
})();
developer-gs commented 3 years ago

The fact that every item needs to have coordinates is a challenge for me. I need to show multiple items in a list, these items are all part of the same collection. Only some of them have coordinates, the others will only receive coordinates at a later stage.. Will I now need to separate Firestore collections and merge them somehow in the client?

MichaelSolati commented 3 years ago

No, you wouldn't need to. GeoCollections require coordinates to add to them:

geocollection.add({
   coordinates: new firebase.firestore.GeoPoint(0, 0)
   name: 'Geofirestore',
   score: 100
});

However geocollections expose the base collection which doesn't require the coordinates.

geocollection.native.add({
   name: 'Geofirestore',
   score: 100
});

So you can do something like this:

const doc = {
   coordinates: new firebase.firestore.GeoPoint(0, 0)
   name: 'Geofirestore',
   score: 100
};

const add = (doc.coordinates) ? geocollection.add : geocollection.native.add;

add(doc);

I'll say test and tinker with that code, I'm kind if rambling through my answer here.