Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG/FEATURE] Possibility to create subcollections, and strange behavior on how to query them? #332

Open
Kontrano opened this issue Feb 24, 2023 · 8 comments
Labels
bug Something isn't working

Comments

@Kontrano
Copy link

Describe the bug
As requested by KyleTheCoder an issue about the unexpected but working method.

I had a few top-level collections before, but I changed to a subcollection structure so I have {collection/document/subcollection/documents} structure.

Now when it comes to queries you would expect that you would have to feed the path into it to get to the subcollection but this doesn't work. Every subcollection with the same name seems to be joined in the backend and treated as a top-level connection which means you have to query the subcollection directly and not include any path.

To Reproduce
Add subcollection
To create a subcollection dynamically create a new document but instead of referencing a single collection as the collection reference feed in a path to the subcollection. as an example: {main-collection/document_id/sub-collection}

func create_document( collection : String, document_id : String, fields : Dictionary):
	var firestore_collection : FirestoreCollection = Firebase.Firestore.collection(collection)
	var add_task : FirestoreTask = firestore_collection.add(document_id, fields)
	var document : FirestoreTask = yield(add_task, "task_finished")
	return document

Query this collection by issuing a query as if it were a top-level collection, doing a path to the collection throws an error

func query(event_id):
	var query : FirestoreQuery = FirestoreQuery.new().from(" &SUBCOLLECTION_ID& ").where("event_id",FirestoreQuery.OPERATOR.EQUAL,event_id)
	var result : Array = yield(Firebase.Firestore.query(query), "result_query")
	return result`

Expected behavior
I would have expected it to need a path to the collection

Environment:
-Windows11

@Kontrano Kontrano added the bug Something isn't working label Feb 24, 2023
@Kontrano
Copy link
Author

Update:
I'm also building another app with Firebase using Flutter and Dart and in that implementation, you do need to specify the subcollection as {main-collection.document_id.sub-collection} but you can also do a compound query which is then called as {sub-collection} which combines all collection with that id. Potentially this is done by default via the Rest api?

@WolfgangSenff
Copy link
Collaborator

Okay, looking at your code, I actually think it's doing it correctly. It looks like your latter guess must be correct: it is taking the main collection ID and using it as the parent to which all subcollections are inspected with the query. I'm going to leave this open for more discussion and for anyone else to chime in, but if I'm reading the Firebase website correctly, that's how it should work for the REST API, at least.

@WolfgangSenff
Copy link
Collaborator

I'm reworking the Firestore part of the plugin and as it turns out, there's a new (or perhaps old and I missed it) way to create collections and subcollections via the REST API. I will implement it and close this when I get to it, just updating to let you know!

@Kontrano
Copy link
Author

Nice thanks for the info, and as always great work on this!

@theSlyest
Copy link
Contributor

theSlyest commented Jul 19, 2024

Hello there, just to say that in my current project I am able to create sub-documents - and therefore sub-collections - and then retrieve them:

var subcollection_path: String = collection_id + "/" + document_id + "/" + subcollection_id
var subcollection : FirestoreCollection = Firebase.Firestore.collection(subcollection_path)
await subcollection.add(subdocument_id, { ... })
[...]
var subdocument = await subcollection.get_doc(subdocument_id)

@WolfgangSenff
Copy link
Collaborator

Yes, that is a known, albeit somewhat of a hack, way to do it. There's an explicit function for it that I have not yet implemented. It's fine (I personally think) to do it that way, but I'd rather implement the explicit function.

@theSlyest
Copy link
Contributor

theSlyest commented Jul 19, 2024

And queries don't work with subdocuments because of the Firebase :runQuery specification: if the collection name contains a slash "/", the HTTP request returns the following result:

[
    {
        "error": {
            "code": 400,
            "message": "Collection id \"[...]\" is invalid because it contains \"/\".",
            "status": "INVALID_ARGUMENT"
        }
    }
]

@WolfgangSenff
Copy link
Collaborator

Hm. I wonder if creating it sort of the "normal" way would fix that. I'm actually not sure - I hadn't realized that. You can definitely do a query that queries over everything in a single collection, but that's not necessarily what anyone wants, since it might be a sub-collection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants