Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display duplicate events after update firestore data, but the data itself in firestore isn't duplicated

I have a web application(Angular) and mobile application(Ionic). Both of them share the same Firestore data.

Use web application update existing data but the ionic app shows duplicate items(the duplicates will be gone after restart the mobile app), I check the item data itself in Firestore, it was updated and unique. Does anyone have any clue on this?

This issue only occurs on the mobile app other than the web app, both of them use "angularfire2": "^5.0.0-rc.4",

   import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';

   this.posts$ = this.db.getRecentPosts().snapshotChanges().pipe(
      map(arr => arr.map(doc => {
          return { id: doc.payload.doc.id, ...doc.payload.doc.data() }
        }
      ))
    );

Did research and it seems like(not 100% sure) an angularfire2 issue: AngularFirestoreCollection sometimes returns duplicate of records after inserting a new record

enter image description here

like image 649
Haifeng Zhang Avatar asked Jun 29 '18 20:06

Haifeng Zhang


People also ask

What is onSnapshot in Firebase?

You can listen to a document with the onSnapshot() method. An initial call using the callback you provide creates a document snapshot immediately with the current contents of the single document. Then, each time the contents change, another call updates the document snapshot.

Is firestore real time?

Firebase offers two cloud-based, client-accessible database solutions that support realtime data syncing: Cloud Firestore is Firebase's newest database for mobile app development. It builds on the successes of the Realtime Database with a new, more intuitive data model.

Why are my firestore reads so high?

Use of the Firebase console will incur reads. If you leave the console open on a collection or document with busy write activity then the Firebase console will automatically read the changes that update the console's display. Most of the time this is the reason for unexpected high reads.

How do I assign data to a document in Cloud Firestore?

Set the data of a document within a collection, explicitly specifying a document identifier. Add a new document to a collection. In this case, Cloud Firestore automatically generates the document identifier. Create an empty document with an automatically generated identifier, and assign data to it later.

What types of data can be stored in Firestore?

Data types. Cloud Firestore lets you write a variety of data types inside a document, including strings, booleans, numbers, dates, null, and nested arrays and objects. Cloud Firestore always stores numbers as doubles, regardless of what type of number you use in your code.

How to avoid overwriting entire documents in Cloud Firestore?

If you're not sure whether the document exists, pass the option to merge the new data with any existing document to avoid overwriting entire documents. Cloud Firestore lets you write a variety of data types inside a document, including strings, booleans, numbers, dates, null, and nested arrays and objects.

How to update data in Firebase FireStore in Android?

How to Update Data in Firebase Firestore in Android? Step 1: Creating a new Activity for updating the data For creating a new Activity navigate to the app > res > layout >... Step 2: Updating our Modal Class where we were storing our data In previous articles, we have seen creating our Modal... Step ...


1 Answers

Since duplicates are gone after restart and other people report this issue as well it feels to me that the problem is within AngularFirestore itself. As a workaround you could try the following:

 import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';

   this.posts$ = this.db.getRecentPosts().snapshotChanges().pipe(
      map(arr => arr.reduce((acc, doc) => { // map -> reduce
        const id = doc.payload.doc.id
        // remove !(id in acc) to get last duplicate
        !(id in acc) && acc[id] = { id, ...doc.payload.doc.data() } 
        return acc }
        }, {} // reduce seed
      )),
      // you can also Object.values(arr.reduce(...)), but this I find bit more readable
      map(coll => Object.values(coll))
    );
like image 197
artur grzesiak Avatar answered Oct 21 '22 23:10

artur grzesiak