Cloud Firestore deep get with subcollection

2019-01-31 05:39发布

Let's say we have a root collection named 'todos'.

Every document in this collection has:

  1. title: String
  2. subcollection named todo_items

Every document in the subcollection todo_items has

  1. title: String
  2. completed: Boolean

I know that querying in Cloud Firestore is shallow by default, which is great, but is there a way to query the todos and get results that include the subcollection todo_items automatically?

In other words, how do I make the following query include the todo_items subcollection?

db.collection('todos').onSnapshot((snapshot) => {
  snapshot.docChanges.forEach((change) => {
    // ...
  });
});

4条回答
Bombasti
2楼-- · 2019-01-31 06:07

I have faced the same issue but with IOS, any way if i get your question and if you use auto-ID for to-do collection document its will be easy if your store the document ID as afield with the title field in my case :

let ref = self.db.collection("collectionName").document()

let data  = ["docID": ref.documentID,"title" :"some title"]

So when you retrieve lets say an array of to-do's and when click on any item you can navigate so easy by the path

ref = db.collection("docID/\(todo_items)")

I wish i could give you the exact code but i'm not familiar with Javascript

查看更多
狗以群分
3楼-- · 2019-01-31 06:07

you could try something like this

db.collection('coll').doc('doc').collection('subcoll').doc('subdoc') 

Hope this helps !

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-01-31 06:24

If anyone is still interested in knowing how to do deep query in firestore, here's a version of cloud function getAllTodos that I've come up with, that returns all the 'todos' which has 'todo_items' subcollection.

exports.getAllTodos = function (req, res) {
    getTodos().
        then((todos) => {
            console.log("All Todos " + todos) // All Todos with its todo_items sub collection.
            return res.json(todos);
        })
        .catch((err) => {
            console.log('Error getting documents', err);
            return res.status(500).json({ message: "Error getting the all Todos" + err });
        });
}

function getTodos(){
    var todosRef = db.collection('todos');

    return todosRef.get()
        .then((snapshot) => {
            let todos = [];
            return Promise.all(
                snapshot.docs.map(doc => {  
                        let todo = {};                
                        todo.id = doc.id;
                        todo.todo = doc.data(); // will have 'todo.title'
                        var todoItemsPromise = getTodoItemsById(todo.id);
                        return todoItemsPromise.then((todoItems) => {                    
                                todo.todo_items = todoItems;
                                todos.push(todo);         
                                return todos;                  
                            }) 
                })
            )
            .then(todos => {
                return todos.length > 0 ? todos[todos.length - 1] : [];
            })

        })
}


function getTodoItemsById(id){
    var todoItemsRef = db.collection('todos').doc(id).collection('todo_items');
    let todo_items = [];
    return todoItemsRef.get()
        .then(snapshot => {
            snapshot.forEach(item => {
                let todo_item = {};
                todo_item.id = item.id;
                todo_item.todo_item = item.data(); // will have 'todo_item.title' and 'todo_item.completed'             
                todo_items.push(todo_item);
            })
            return todo_items;
        })
}
查看更多
Evening l夕情丶
5楼-- · 2019-01-31 06:30

This type of query isn't supported, although it is something we may consider in the future.

查看更多
登录 后发表回答