14
votes

I have been working on transitioning a small Firebase project to the new, similar Firestore db because of its more queryable nature, but I am having a trouble with a simple query problem.

I am trying to get all documents in a collection, in the case each document is a club and the collection is all of the clubs.

In Firebase, I was able to do something like:

export function fetchClubs() {
    const Club = firestore.ref('clubs');
    return dispatch => {
        Club.on('value', snapshot => {
            dispatch({
                type: FETCH_CLUBS,
                payload: snapshot.val()
            })
        })
    }
}

snapshot would have all the information i needed inside of it.

I am trying to replicate this with Firestore, but have an only been able to come across a solution that involves making a new array and looping over the results then adding each result to that.

Here is my Firestore attempt using the slightly different Firestore syntax

export function fetchClubsStore() {
    const Clubs = firestore.collection('clubs');
     return dispatch => {
        Clubs.get().then(querySnapshot => {
            console.log("clubs snapshot: ", querySnapshot)
            dispatch({
                type: FETCH_CLUBS,
                payload: querySnapshot.val()
            })
        })
    }
}

If you have any ideas, all help will be greatly appreciated! Thanks!

(this is my first stackoverflow post, go easy! :) )

Edit:

Example from Firestore docs of how to get all documents in a collection.

db.collection("cities").where("capital", "==", true)
.get()
.then(function(querySnapshot) {
    querySnapshot.forEach(function(doc) {
        console.log(doc.id, " => ", doc.data());
    });
})
.catch(function(error) {
    console.log("Error getting documents: ", error);
});

Edit 2:

My new solution to get the documents in a usable array by using .docs and .data() . Still seems inefficient, as I am having to loop over the doucments and extract the usable information one by one.

export function fetchClubsStore() {
const Clubs = firestore.collection('clubs');
var clubs = [];
return dispatch => {
    Clubs.get().then(querySnapshot => {
        console.log("clubs snapshot: ", querySnapshot.docs)
        _.each(querySnapshot.docs, function(data){
            clubs.push(data.data());
        })
        dispatch({
            type: FETCH_CLUBS,
            payload: clubs
        })
    })
}

}

1
Have you tried working out your query separately from all the noise of Redux actions? This example would be much easier to troubleshoot with only the database involved, and not also your application state.skylize
I don't understand what issue you're trying to solve (I don't see any loop in either of your code snippets). For what it's worth, querySnapshot.val() is invalid since there's no .val method on QuerySnapshot in Firestore. You might want .docs for the array of DocumentSnapshot objects in the QuerySnapshot or something, but it's not clear from your question.Michael Lehenbauer
@MichaelLehenbauer I am not using a loop in my current attempt at a solution, but have put an example of the kind of loop I am talking about in an edit to my original post. I was able to get an array of DocumentSnapshot objects using the .docs method you suggested, but this data doesn't seem particularly usable until I loop through it and get the .data() of each document individually. Is there a better way to get the information from the documents into a usable array? Thanks.Austin Wrenn
@AustinWrenn You could do var clubs = querySnapshot.docs.map(doc => doc.data()); to save a bit of code.Michael Lehenbauer
@MichaelLehenbauer thanks you! ;)Adriano Resende

1 Answers

1
votes

The difference between Firebase Realtime Database and Firestore is that RTDB is basically just a cloud hosted JSON object. So there is no concept of documents and there is no collections of data.

The value object in a query snapshot that you retrieve from RTDB is just a JSON object. Hence you can access first level nodes by their keys (and also any level nodes by their keys)

If you're coming from RTDB you'll notice the difference that Cloud Firestore has collections and documents. So your query results will inherently be collections of data rather than a JSON object. The documents that are retrieved from a query can not be grabbed as a single big JSON object.

Looping over the query result is the correct way to work with Cloud Firestore.