6
votes

I'm building a React Native app with Expo using the Firebase web api and trying to retrieve a collection of documents from my Firestore project. According to the documentation over at https://firebase.google.com/docs/firestore/query-data/get-data I should be able to iterate over a collection using the forEach() method provided by the collection snapshot like so:

db
.collection('services')
.get()
.then(snapshot => {
  snapshot.forEach(doc => {
    if (doc && doc.exists) {
      console.log(doc.id, ' => ', doc.data());
    }
  });
});

This however only logs one document, despite the fact that I currently have 3 documents in the collection, what am I missing? Please help.

My firebase config looks like so:

import * as firebase from 'firebase';
 firebase.initializeApp({
    "projectId": "my-project-id",
    "apiKey": "my-api-key",
    "authDomain": "my-project.firebaseapp.com",
    "databaseURL": "https://my-project.firebaseio.com",
    "storageBucket": "my-project-id.appspot.com/",
    "messagingSenderId": "my-messaging-sender-id"
})
const db = firebase.firestore();
3
Are the other two documents empty? Can you send a screenshot of your db structure?tugce
@tugce I've got data in the other two documents, and when I log only the document id or metadata it all displays in my console, its just when I call the data() method that only one document displays.Pip

3 Answers

2
votes

I finally got it after a bit debugging. Looks like what I needed to do was use the _document.data property on each snapshot returned by the forEach on the querySnapshot. So my code now looks like so:

db
    .collection('services')
    .get()
    .then(snapshot => {
      snapshot
        .docs
        .forEach(doc => {
          console.log(JSON.parse(doc._document.data.toString()))
        });
    });

This feels like a bit of a hack but logging just doc._document.data returns a lot of metadata along with each document, toString() returns just the document data but as a JSON string so then I parse it into a JavaScript object with JSON.parse.

2
votes

Hey to retrieve data from Firestore here is an explanation and a working snippet / App example.

This example works both on Reactjs and React Native, However I cant share the RN example as that belongs to a customer.

Explanation:

• With firestore you must convert an Array-Like value into a true value and this is done with the forEach((doc) => {} = doc.data();}

• Then use the push() method to append the value into an Array.

• After which you can use setState to define your dataSource linked with state.

• then you can render your data onto the UI.

here is a demo react app project I have created which pushes and pulls data from cloud firestore along with a working component snippet example below.

source code: https://github.com/trackmystories/Checkout-challenge

video example : https://drive.google.com/file/d/1XAGjyJU-QiuolNmtUVyjg9tQAloeyABj/view?usp=sharing

import React, {Component} from 'react'
import "firebase/firestore"
import * as firebase from 'firebase';
import { firebaseConfig } from '../api/config'



export default class CommentsTab extends Component {

  constructor(props) {
  super(props);
  if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig);
  }
  this.ref = firebase.firestore().collection('Comment').orderBy('date', 'desc').limit(10);
  this.state={
  dataSource : []
}
}

componentDidMount(){
  this.unsubscribe = this.ref.onSnapshot(this.latestComments);
}



latestComments = (commentsSnapShot) =>{
  const Comment = [];
  commentsSnapShot.forEach((doc) => {
  const {name, email, date, comment} = doc.data();
    Comment.push({
      key: doc.id,
      name,
      email,
      date,
      comment
    });
  });
  this.setState({
    dataSource : Comment,
  });
}




  render(){
     const {dataSource} = this.state
    return(

    )
  }
}
0
votes

Alternative, you can also use a lib like firestorter to seamlessly integrate Firestore into React

https://medium.com/@hrutjes/building-a-react-firestore-app-with-zero-effort-and-mobx-525df611eabf