简体   繁体   中英

Get all collections from a document Firebase

I'm building a fullstack todo app using firebase to store user information. My idea is that each user can create multiple lists and write multiple 'todos' in every list (eg. Have a list for today and another for tomorrow). My data is structured in this manner:

火库查询问题

users (collection) -> usersID (every user is a document) -> todos Lists (collection) -> todoId (document) -> (object with the data)

I can't seem to be able to query the multiple lists a user might have (by default, I'm currently just retriving data from the 'todos' collection). Either I'm failing to see some firestore functionality or I'm not structuring my database correctly. Any advice?

You are structuring your data fine. The problem is that the Firebase Client SDK doesn't offer a function to retrieve all subcollections a document has. To solve your problem you got multiple options.

1. The cleanest but most exhaustive way

You upgrade to the Blaze Plan and use Firebase Functions with the Admin SDK. The Admin SDK offers a function called listCollections() which exactly does what you want. The disadvantage is that Firebase Functions have something called coldstart which means that when your function was idle for some minutes it takes up to 20 seconds (from my experience) to run again after you called it, which can be really frustrating. Otherwise you can run a free node.js server on something like Heroku to use the Admin SDK there to avoid coldstart (better option in my opinion). The Admin SDK is explicitly not meant to be used on the client side. Check this thread

2. List all your todo lists (easiest way)

Everytime the user creates a new list, you add that to an array in your users document like this:

// Representation of your user document
user
    name: "Florian"
    lists: [
        "todos",
        "anotherList"
    ]

So in that way you can just fetch your user, get the lists property from it and call all lists with a loop over the lists array. As alternative just display the lists content and let the user open it explicitly to save reads.

3. Restructuring your database (I would recommend it)

If you don't have a lot of data yet, I would recommend to restructure your database like:

users - the collection with all your users (without the todo list subcollections

lists - containing a document for every created list
      - each document contains a field with `owner`
      - each document contains a field with the list name
      - each document owns a subcollection with todos

If you use this way you could just query the database like

const getLists = async () => {
    const ref = collection(db, 'lists');
    const q = query(ref, where('owner', '==', theUserYouWantToQuery);
    // returns array with all list (including listname) of that user.
    const lists = (await getDocs(q)).docs.map(doc => ({ ...doc.data(), doc.id }));
}

when you have all list objects from that user you can either loop over that array to get all todos in the lists or let the user only fetch one list by opening it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM