MichaelSolati / geofirestore-js

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

.near() and .where() are not compatible #190

Closed BryanEnid closed 4 years ago

BryanEnid commented 4 years ago

[REQUIRED] Describe your environment

[REQUIRED] Describe the problem

GeoQuery Instance was returned but it cannot get the provided data from firestore

Steps to Reproduce

  1. Create a firestore document with a status and a coordinate
    geoCollection.add({
    status: "active",
    coordinates: new firebase.firestore.GeoPoint(33.9275167, -84.2741967),
    `});
  2. Then try to query it like so:
    let query = geoCollection
    .near({ center: new firebase.firestore.GeoPoint(33.9275167, -84.2741967), radius: 1000 })
    .where("status", "==", "active");

Relevant Code

This works:

let query = geoCollection.near({ center: new firebase.firestore.GeoPoint(latitude, longitude), radius: radius })

Also this:

let query = geoCollection.where("status", "==", "active");

But not together:

let query = geoCollection
    .near({ center: new firebase.firestore.GeoPoint(33.9275167, -84.2741967), radius: 1000 })
    .where("status", "==", "active");

// backwards either
let query = geoCollection
    .where("status", "==", "active");
    .near({ center: new firebase.firestore.GeoPoint(33.9275167, -84.2741967), radius: 1000 })
MichaelSolati commented 4 years ago

Do you use the get method or the onSnapshot listener? Either way I'm thinking that the database isn't indexed to support this and the error isn't surfacing. Can you try a catch statement if you're using get or a error handler function for onSnpashot?

BryanEnid commented 4 years ago

Hey, thanks for replying back. I have used onSnapshot. There is no error whatsoever. It's just that it doesn't do the query as specified. It doesn't get the data back.

    const firestore = firebase.firestore(); 
    const GeoFirestore = geofirestore.initializeApp(firestore); 
    const geoCollection = GeoFirestore.collection("restaurants"); 

    // Queries NOT WORKING when using both at the same time
    let query = geoCollection
      .near({ center: new firebase.firestore.GeoPoint(latitude, longitude), radius: radius })
      .where("status", "==", "active");

    const unsubscribe = query.onSnapshot((res) => 
      res.docChanges().forEach((change) => {
        switch (change.type) {
          case "added":
            console.log(change.doc.data()); // I"M NOT GETTING DATA and there is no error.
            return addJob(change.doc.id, change.doc.data());
          case "modified":
            return updateJob(change.doc.id, change.doc.data());
          case "removed":
            return removeJob(change.doc.id);
          default:
            break;
        }
      });
    });

But if I do this instead:

    const firestore = firebase.firestore(); // Create a Firestore reference
    const GeoFirestore = geofirestore.initializeApp(firestore); // Create a GeoFirestore reference
    const geoCollection = GeoFirestore.collection("restaurants"); // Create a GeoCollection reference

    // =========================================================
    let query = geoCollection
      // .near({ center: new firebase.firestore.GeoPoint(latitude, longitude), radius: radius })
      .where("status", "==", "active"); 

    // OR 

    let query = geoCollection
      .near({ center: new firebase.firestore.GeoPoint(latitude, longitude), radius: radius });
      // .where("status", "==", "active")
   // ==========================================================

    const unsubscribe = query.onSnapshot((res) => 
      res.docChanges().forEach((change) => {
        switch (change.type) {
          case "added":
            console.log(change.doc.data()); // I DO GET THE DATA   <------------------------------------
            return addJob(change.doc.id, change.doc.data());
          case "modified":
            return updateJob(change.doc.id, change.doc.data());
          case "removed":
            return removeJob(change.doc.id);
          default:
            break;
        }
      });
    });

Here is the structure of firebase: image

MichaelSolati commented 4 years ago

Hey @BryanEnid I hope you're closing the issue because you were able to resolve the issue, out of curiosity what was the solution?

BryanEnid commented 4 years ago

Hey, @MichaelSolati. Yeah, I could solve It. It was all my fault. First of all, thanks for helping me out and giving maintenance to such a great tool.

I had to create an Index in the Firestore Console to be able to use where() and near() together. I found this when I actually tried to console log doc.data() with the get() method and I got a response with the next log:

image

[FirebaseError: The query requires an index. You can create it here: (SOME URL)]

But one thing is certain, I didn't get this message with the onSnapshot response.