0

I am trying to loop through a List to add each item to a google firestore doc. However, the problem I am facing is that ONLY the last item in the List is added to the doc.

Note: The line print("=== $i POST SUCCESSFULLY ADDED ====") prints incremental for 5 times as expected

QUESTION: How can I get this loop to add all items to the firestore doc?

  void addPost() {
    DocumentReference documentReferencer = _firestore.collection('posts').doc();
    var i = 0;
    while (i < 5) {
      documentReferencer.set(postsData[i]);
      print("=== $i POST SUCCESSFULLY ADDED ===="); //PRINTS 5 TIMES
      i++;
    }
  }
Ian Rajkumar
  • 149
  • 1
  • 8

2 Answers2

1

I don't exactly know what your problem is in here, but it looks like your code is ignoring the fact that POST-ing data to a server is an asynchronous operation.

In other words, I'd expect that you need to await that to happen.

Also, I'd refactor the loop for readability.

Your code should be something like:

Future<void> addPost() async {
    DocumentReference documentReferencer = _firestore.collection('posts').doc();
    for(final post in postsData) {
      await documentReferencer.set(post);
      print("=== $i POST SUCCESSFULLY ADDED ===="); //PRINTS 5 TIMES
    }
  }
venir
  • 1,809
  • 7
  • 19
  • 1
    As nothing is happening after `set()` using an `async` function with `await` should not be necessary. And also because the order in which the items are written to the database does not matter using a sync call is perfectly fine. The only issue is that the information in the print statement is wrong because at that point the item did not finish writing to the database. Also we do not know if the action was successful. – Jan Nov 16 '21 at 15:17
  • True that. Care to share more context, or code, so that I can look into it? – venir Nov 16 '21 at 16:13
  • 1
    I am not sure what exactly you want to know but see my answer below for additional information to the original question. I hope that helps. – Jan Nov 19 '21 at 15:33
1

In fact all items are written to the doc but you keep overwriting the document with the next item ending up with only the last item.

When calling set() you should use SetOptions to set merge to true like so.

  void addPost() {
    DocumentReference documentReferencer = _firestore.collection('posts').doc();
    var i = 0;
    while (i < 5) {
      documentReferencer.set(postsData[i], SetOptions(merge: true));
      print("=== $i POST SUCCESSFULLY ADDED ===="); //PRINTS 5 TIMES
      i++;
    }
  }

Alternatively use update(). Attention: This will fail if the document does not exist yet.

  void addPost() {
    DocumentReference documentReferencer = _firestore.collection('posts').doc();
    var i = 0;
    while (i < 5) {
      documentReferencer.update(postsData[i]);
      print("=== $i POST SUCCESSFULLY ADDED ===="); //PRINTS 5 TIMES
      i++;
    }
  }

I recommend you debugging your code step by step while keeping an eye on the database. Then you can see how you keep overwriting the doc.

Also be aware that you are not catching any errors in case the database calls go wrong. So you can't tell if the action was successful. The only thing you know at the point of your print() is that the request was sent to Firebase.

Further readings:

Jan
  • 150
  • 3
  • 11