mobizt / Firebase-ESP-Client

[DEPRECATED]🔥Firebase Arduino Client Library for ESP8266, ESP32 and RP2040 Pico. The complete, fast, secured and reliable Firebase Arduino client library that supports RTDB, Cloud Firestore, Firebase and Google Cloud Storage, Cloud Messaging and Cloud Functions for Firebase.
MIT License
471 stars 100 forks source link

Firestore #535

Closed DiSkyMaster closed 1 year ago

DiSkyMaster commented 1 year ago

I'm sorry if I didn't follow the format or if I opened an issue incorrectly.

I just have a problem and I'm not sure how to do it. My firebase firestore database information is as in the image below. I login with nodemcu by entering my email and password. But I only know X220 without knowing the user's uid. X220 is unique information. Only one user can have one. So when I know that, I can only know that it belongs to that user. Anyway, my goal is to edit the blue, red, white information of the X220 (it doesn't matter which user it belongs to). For example like here whereEqualTo("devices", "X220")

In summary, I want to get and edit the blue, red, white information of a unique device ID named X220, which has hundreds of users and only one device out of dozens of devices.

image image

mobizt commented 1 year ago

You should read the Firestore REST API documentation for what features that API provided.

For your required feature, please try this example first to see how you can filter with runQuery function.

Then you should compose your query with StructuredQuery from this document. https://cloud.google.com/firestore/docs/reference/rest/v1/StructuredQuery

From the doc, you will see the where query that can be composed from one of the filters i.e., compositeFilter, fieldFilter and unaryFilter.

The FieldFilter will match your requirement with EQUAL operator.

I'm never try with this feature in dept and I'm quite sure that this matches your requirement.

DiSkyMaster commented 1 year ago

I'm not sure of its accuracy. I tried several times but couldn't get the result I wanted. How should I go about this?

In my last few attempts and in the code above I also get the following error:


    FirebaseJson query;
    query.set("where/fieldFilter/field/fieldPath", "devices");
    query.set("where/fieldFilter/op", "EQUAL");
    query.set("where/fieldFilter/value/stringValue", "X220");
    query.set("limit", 1);

    if (Firebase.Firestore.runQuery(&fbdo, FIREBASE_PROJECT_ID, "", "users", &query))
      Serial.printf("ok\n%s\n\n", fbdo.payload().c_str());
    else
      Serial.println(fbdo.errorReason());```
mobizt commented 1 year ago

The Firestore 's StructuredQuery is similar to SQL language used in rational database.

Your StructuredQuery is missing "select" and "from" queries.

DiSkyMaster commented 1 year ago

Thank you for your return. I made a few more attempts. I'm still getting the same error. The last example I tried:

    query.set("select/fields/[0]/fieldPath", "red");
    query.set("select/fields/[1]/fieldPath", "blue");
    query.set("select/fields/[2]/fieldPath", "white");

    query.set("from/collectionId", "devices");
    query.set("from/allDescendants", false);

    query.set("where/fieldFilter/field/fieldPath", "devices");
    query.set("where/fieldFilter/op", "EQUAL");
    query.set("where/fieldFilter/value/stringValue", "X220");

    query.set("limit", 1);
mobizt commented 1 year ago

The document path "users" is not valid. It should be full path of document that contains the collection "devices".

In your case, the valid document path is. "users/EaHGDj4eI3dgr3eoiP3PH7yIPm12"

This is not valid. query.set("where/fieldFilter/field/fieldPath", "devices");

Which "devices" is collection id not a field.

Please see the data model doc.

I don't think that data query was designed for document id filtering, instead of data (field) filtering.

In your case, I recommend you storing your document name as a field in that document too and query from that field.

For example, if the field "user_id" used to store its document id like the following.

Field "user_id" in document "user1" store value "user1". Field "user_id" in document "user2" store value "user2". Field "user_id" in document "X220" store value "X220".

Then you can use.

query.set("where/fieldFilter/field/fieldPath", "user_id");

DiSkyMaster commented 1 year ago

Thanks for your return. I think I'm on the right track. I have now added an id field next to the blue, red, white fields. I set this id as X220. And my code is now like this:

    FirebaseJson query;

    query.set("select/fields/[0]/fieldPath", "red");
    query.set("select/fields/[1]/fieldPath", "blue");
    query.set("select/fields/[2]/fieldPath", "white");

    query.set("from/collectionId", "devices");
    query.set("from/allDescendants", false);

    query.set("where/fieldFilter/field/fieldPath", "id");
    query.set("where/fieldFilter/op", "EQUAL");
    query.set("where/fieldFilter/value/stringValue", "X220");

    query.set("limit", 1);

    if (Firebase.Firestore.runQuery(&fbdo, FIREBASE_PROJECT_ID, "", "devices/X220", &query))
      Serial.printf("ok\n%s\n\n", fbdo.payload().c_str());
    else
      Serial.println(fbdo.errorReason());

When I use it this way it gives me the ok return and the following output. But I still can't get the blue, red, white field.

[
    {
        "readTime":"2023-07-29T09:35:39.286903Z"
    }
]
mobizt commented 1 year ago

You should read my previous post carefully.

The document at the path "devices/X220" you provided in Firebase.Firestore.runQuery does not contains the collection "devices".

I already show your correct document path and it should be absolute path from root.

DiSkyMaster commented 1 year ago

The ESP needs to do this without knowing "EaHGDj4eI3dgr3eoiP3PH7yIPm12". The device with the id of X220 will not know which user uid it has. This X220 can only be in one user. For example, let it be the user with the uid "EaHGDj4eI3dgr3eoiP3PH7yIPm12". ESP, on the other hand, will attract the user who owns this X220 with runQuery and reach the devices it owns and the fields of the devices. This is my aim.

That's why I can't write "users/EaHGDj4eI3dgr3eoiP3PH7yIPm12" in path. How can I do this differently without knowing the "EaHGDj4eI3dgr3eoiP3PH7yIPm12" information? How should I set this up?

mobizt commented 1 year ago

It's not possible to do what you need.

This is Firestore not Firebase RTDB database which they have different data model.

You should keep in mind what is Firestore data model which it stated clearly in the Firestore documentation.

mobizt commented 1 year ago

You should avoid leaving blank document name when creating/committing the document because it will create document with random UID as you get which unpredictable for further access.

mobizt commented 1 year ago

You should ask this such question on the community forum or contact google support team.