googleapis / nodejs-firestore

Node.js client for Google Cloud Firestore: a NoSQL document database built for automatic scaling, high performance, and ease of application development.
https://cloud.google.com/firestore/
Apache License 2.0
642 stars 149 forks source link

GeoPoint lat/lon wrong typings #33

Closed rodrigoreal closed 6 years ago

rodrigoreal commented 7 years ago

When i save an item using the GeoPoint class like that: new firestore.GeoPoint(location.lat, location.lng), it is saving on the database with an underscore prefix: _latitude and _longitude, but when i try to retrieve it the GeoPoint class force us to use latitude and longitude objects:

  export class GeoPoint {
    /**
     * Creates a new immutable GeoPoint object with the provided latitude and
     * longitude values.
     * @param latitude The latitude as number between -90 and 90.
     * @param longitude The longitude as number between -180 and 180.
     */
    constructor(latitude: number, longitude: number);

    readonly latitude: number;
    readonly longitude: number;
  }

If i do inspect my GeoPoint variable on my code here is what i get: { _latitude: -25.6173489, _longitude: -41.238464 } So for the moment i can't use the GeoPoint typings.

captura de tela 2017-10-06 as 19 21 42

seller.location.latitude returns undefined (<any>seller.location)._latitude returns the latitude value

schmidt-sebastian commented 6 years ago

Thanks for reporting this, I will try to push a fix for this in the next release.

schmidt-sebastian commented 6 years ago

@rodrigoreal How are you saving the GeoPoint? As a top-level entity or within an object? We currently only support GeoPoints within a different object.

rodrigoreal commented 6 years ago

@schmidt-sebastian I'm saving it as an object on my seller entity.

const seller: SellersInterface = {
  name: body.name,
  location: new firestore.GeoPoint(lat, lng)
};
admin.firestore().collection('sellers').add(seller);
export interface SellersInterface {
  id?: string;
  name: string;
  location: firestore.GeoPoint;
}

I'm doing something wrong?

schmidt-sebastian commented 6 years ago

The Firestore SDK can only recognize types that are part of its own namespace. Since you are using Firestore through the Admin SDK, you need to save GeoPoints as follows:

admin.firestore().collection('sellers').add({
   location:new admin.firestore.GeoPoint(1.0, 1.0)
});

I'm going to close this issue for now. If the above doesn't help, please feel free to re-open.

amitransinha commented 6 years ago

Hi, not able to save geo point. I am doing the same as you mentioned above but it does not help me. Please have a look on my code.


const admin = require("firebase-admin"); const serviceAccount = require(process.env.FBASE_AUTH_FILE); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: process.env.dbURL }); let d = new Date(); let data = {
name: 'Amit', location: new admin.firestore.GeoPoint(28.52038,77.28073), created_at: d.getTime() } setDoc = db.collection('users').doc().set(data); if (setDoc) { console.log('User added'); }

// Error which I am receiving is as follows. Error: Cannot encode type ([object Object]) to a Firestore Value

schmidt-sebastian commented 6 years ago

@amitransinha

Where are you getting Firestore from ('db')? If I add the following, your code works:

const Firestore = admin.firestore;
const db = Firestore();

At the moment, you can't mix and match the instances returned from GCloud and the Firebase Admin SDK.

amitransinha commented 6 years ago

@schmidt-sebastian Thanks.. It work.

Yes, i was using the GCloud instance to save data in collection. I am facing one more issue with firestore. Can I fetch data from multiple collections using join? As we can do same in MySQL and MongoDB as well.

Your response will be much appreciable.

schmidt-sebastian commented 6 years ago

We currently don't expose a join operation. If you know the keys of your data, you can use getAll() on the main Firestore class.

surya-fleetrun-in commented 1 year ago

When I use a google cloud function written in typescript to retrieve a document containing Geopoint, I am hitting the same issue with the response containing _latitude and _longitude for geopoint.

const Firestore = admin.firestore;
const db = Firestore();
const snap = await db
      .collection("addresses")
      .doc(docId)
      .get();
const snapdata = snap.data();
console.log(snapdata);
MarkDuckworth commented 1 year ago

@surya-fleetrun-in, when I run this code, I see this logged:

{
  point: GeoPoint {
    _latitude: 44.04818119788449,
    _longitude: -109.7278059330043
  }
}

It looks like console.log(snapdata) is logging the private properties of the GeoPoint object.

However, the returned point object is an instance of the GeoPoint class, so you should be able to use the latitude and longitude getters.

console.log(snapdata['point'].latitude);
console.log(snapdata['point'].longitude);

I tested using firebase-admin@11.10.1.

surya-fleetrun-in commented 1 year ago

Thanks @MarkDuckworth the postman response is also showing the private properties, which confused us a little, but the getter seems to work.