0

I'm trying to create a geoquery in node.js from Firestore, but when using the example from the Firebase library (https://firebase.google.com/docs/firestore/solutions/geoqueries#query_geohashes), my code returns 'Cannot read properties of null (reading 'text')'.

I want to query for any nearby users in my 'availableDrivers' collection in firebase, based on my current latitude and longitude (hardcoded to a point less than 1km away from the geopoint stored in 'availableDrivers').

Attached is a photo of the database

enter image description here

What is wrong with my code:

import * as functions from 'firebase-functions';
import { catchErrors } from './helpers';
const admin = require('firebase-admin');
const db = admin.firestore();
import * as geofire from 'geofire-common';

export const createFindDriver = async (latitude: number, longitude: number) => {


    // Find cities within 50km of location
    
    const radiusInM = 50 * 1000;

    const bounds = geofire.geohashQueryBounds([latitude, longitude],radiusInM);
    const promises = [];
    for (const b of bounds) {
    const q = db.collection('availableDrivers')
        .orderBy('geohash')
        .startAt(b[0])
        .endAt(b[1]);

        promises.push(q.get());
    }

    Promise.all(promises).then((snapshots) => {
        const matchingDocs = [];

        for (const snap of snapshots) {
            for (const doc of snap.docs) {
                
                const lat = doc.get('driverLat');
                const long = doc.get('driverLong');

                const distanceInKm = geofire.distanceBetween([lat, long], [latitude, longitude]);

                const distanceInM = distanceInKm * 1000;
                if (distanceInM <= radiusInM) {
                    matchingDocs.push(doc.data());
                }

            }
        }

        return matchingDocs;
    })
    .then((matchingDocs) => {
        console.log(matchingDocs);
    })
    .catch((error) => {
        console.log(error);
    });

}


export const findDriver = functions.region('europe-west2').https.onCall( async (data, context) => {

    const latitude = data.latitude;
    const longitude = data.longitude;

    return catchErrors(createFindDriver(latitude, longitude));

});

Here is my function when it is called:

const findDriver = httpsCallable(functions, 'findDriver');

findDriver({ 
  latitude: 51.513958,
  longitude: -0.0858491,
}).then((result) => {
  /** @type {any} */
  const data = result.data;
  const message = data.text;
  console.log(data);
  console.log(message);
}).catch((error) => {
  console.log("error.message: " + error.message);
});
James 666
  • 1,560
  • 1
  • 15
  • 27

1 Answers1

0

From a quick glance it seems that your createFindDriver returns an array of promises, so you need to handle that array on the result. Assuming that catchErrors doesn't do anything with the result, that'd be:

findDriver({ 
  latitude: 51.513958,
  longitude: -0.0858491,
}).then((result) => {
  result.forEach((data) => {
    const message = data.text;
    console.log(data);
    console.log(message);
  });
}).catch((error) => {
  console.log("error.message: " + error.message);
});
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807