invertase / dart_firebase_admin

🔥 A Firebase Admin SDK for Dart.
Apache License 2.0
118 stars 32 forks source link

Fetching collections with `+` characters in their path #51

Open a-shine opened 1 month ago

a-shine commented 1 month ago

Describe the bug When attempting to fetch documents from a collection using the firestore.collection("/collection+a/lF1kvtRAYMqmdInT7iJK/subcollection").get() the snapshot always returns snapshot.docs.length as 0 if the provided path contains a + character.

To Reproduce Created 2 identical collection hierarchies:

Both contain a single document (again with the same id sTPO9C0HbZJUlKcm1QwR for control)

QuerySnapshot snapshot = await firestore
        .collection("/collectiona/lF1kvtRAYMqmdInT7iJK/subcollection")
        .get();
print('Number of documents: ${snapshot.docs.length}'); // returns 1

QuerySnapshot snapshot = await firestore
        .collection("/collection+a/lF1kvtRAYMqmdInT7iJK/subcollection")
        .get();
print('Number of documents: ${snapshot.docs.length}'); // returns 0

Expected behavior I would expect the + character to have no impact on returning a collection as it is a valid character for a collection path.

HeySreelal commented 1 week ago

I spent some time on this today and want to add a little more debugging information on this for anyone referring this.

When + character is present in the path, especially when used with sub collections it is treated a s space character (`), ie.,/collection+a/abc/subcolis treated as/collection a/abc/subcol`. Which pretty much seems like a encoding issue.

Which in turn means:

  1. This works fine as intended, outputs Number of documents: 1 (or the number of documents correctly)

    final snapshot = await db.collection("collection+a").get();
    print('Number of documents: ${snapshot.docs.length}');
  2. Setting up a collection & document like "collection a/abc/subcol/xyz" and running:

    final snapshot = await db.collection("collection+a/abc/subcol").get();
    print('Number of documents: ${snapshot.docs.length}');

Interestingly outputs, Number of documents: 1

@rrousselGit, just CC-ing you, I'll try to dig in further, if you have any leads on this please let me know, thanks :)

Ehesp commented 1 week ago

Might be worth looking at the node sdk here and validating if it's encoding the path value sent with requests.

HeySreelal commented 6 days ago

Hi @Ehesp, I tried looking into both libraries and inspected the requests.

On NodeJS SDK the request looks something like this:

{
  parent: 'projects/project_id/databases/(default)/documents/collection+a/abc',
  structuredQuery: {
    from: [ { 'collectionId': 'subcol' } ]
  }
}

While on this library, we call the parent: projects/project_id/databases/(default)/documents/collection+a/abc with body:

{
  "structuredQuery": {
    "from": [{ "collectionId": "subcol" }]
  }
}

Which pretty much looks same. Apart from that, there's two specific headers NodeJS library add, google-cloud-resource-prefix and x-goog-request-params, that we don't. Anyway, that also doesn't seems be causing the issue.

May be I'm missing something?