Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cloud Firestore - ensuring data consistency

My database uses redundant data to speed up fetches and minimise the number of documents that need to be read for certain queries. For example I'd store the names of followed users in a map in a users document so I don't have to read another document to retrieve the names of each of the followed users.

User: (Collection) {
    userID: (Document) {

    //user state
    name: ...

    followingUsers: (Map) {
        followingUserID: nameOfUser,
        followingUserID: nameOfUser
    }
}

}

If a user was to change their name, what is the best way to propagate these changes to all places with the redundant data?

like image 482
iCode101 Avatar asked Jan 12 '18 11:01

iCode101


People also ask

Is Firestore strongly consistent?

Firestore in Datastore mode Eventual consistency: Datastore queries become strongly consistent unless you explicitly request eventual consistency. Queries in transactions are no longer required to be ancestor queries.

What are the benefits of using Google Firestore?

With Cloud Firestore, you can automatically synchronize your app data between devices. We'll notify you of data changes as they occur so you can easily build collaborative experiences and realtime apps. Your users can access and make changes to their data at any time, even when they're offline.

What is Firestore persistence?

With offline persistence enabled, the Cloud Firestore client library automatically manages online and offline data access and synchronizes local data when the device is back online. ... For Android and iOS, offline persistence is enabled by default.

Is cloud Firestore better than Realtime Database?

It builds on the successes of the Realtime Database with a new, more intuitive data model. Cloud Firestore also features richer, faster queries and scales further than the Realtime Database. Realtime Database is Firebase's original database.


1 Answers

Good question! For starters, I'd recommend doing this kind of administrative task in a server SDK or cloud function, since you don't want a client to necessarily have the ability to start mucking with every single User doc.

The good news is that, once you start using the server SDKs, you can then put a query into a transaction. So let's say user_123 changes their name from "Jenny" to "Jen". Your transaction would look something like this in pseudo-code:

  • Start Transaction
    • transaction.get(usersRef.where("followingUsers.user_123", ">=", ""))
    • Loop through query results. Grab the doc_id from each doc and use that to start building out the writes in your transaction.
      • transaction.update("/users/<doc_id>/", {"followingUsers.user_123" : "Jen"})
    • Also make sure you add transactions.update("/users/user_123", {"name": "Jen"})
  • End transaction

This general approach would also work on the client-side, but you just wouldn't be able to do this in a transaction. (You could still put all of these changes into a batch write, though.)

like image 51
Todd Kerpelman Avatar answered Nov 08 '22 21:11

Todd Kerpelman