Save to 3 firebase locations with a slow internet connection

598 views Asked by At

Sometimes I'm having issues with firebase when the user is on a slow mobile connection. When the user saves an entry to firebase I actually have to write to 3 different locations. Sometimes, the first one works, but if the connection is slow the 2nd and 3rd may fail.

This leaves me with entries in the first location that I constantly need to clean up.

Is there a way to help prevent this from happening?

            var newTikiID = ref.child("tikis").push(tiki, function(error){

                if(!error){

                    console.log("new tiki created")

                    var tikiID = newTikiID.key()

                    saveToUser(tikiID)
                    saveToGeoFire(tikiID, tiki.tikiAddress)

                } else {

                    console.log("an error occurred during tiki save")

                }

            });
2

There are 2 answers

0
Kato On BEST ANSWER

There is no Firebase method to write to multiple paths at once. Some future tools planned by the team (e.g. Triggers) may resolve this in the future.

This topic has been explored before and the firebase-multi-write README contains a lot of discussion on the topic. The repo also has a partial solution to client-only atomic writes. However, there is no perfect solution without a server process.

It's important to evaluate your use case and see if this really matters. If the second and third writes failed to write to a geo query, chances are, there's really no consequence. Most likely, it's essentially the same as if the first write had failed, or if all writes had failed; it won't appear in searches by geo location. Thus, the complexity of resolving this issue is probably a time sink.

Of course, it does cost a few bytes of storage. If we're working with millions of records, that may matter. A simple solution for this scenario would be to run and audit report that detects broken links between the data and geofire tables and cleans up old data.

If an atomic operation is really necessary, such as gaming mechanics where fairness or cheating could be an issue, or where integrity is lost by having partial results, there are a couple options:

1) Master Record approach

Pick a master path (the one that must exist) and use security rules to ensure other records cannot be written, unless the master path exists.

".write": "root.child('maste_path').child(newData.child('master_record_id')).exists()"

2) Server-side script approach

Instead of writing the paths separately, use a queue strategy.

  1. Create an single event by writing a single event to a queue
  2. Have a server-side process monitor the queue and process events
  3. The server-side process does the multiple writes and ensures they all succeed
  4. If any fail, the server-side process handles rollbacks or retries

By using the server-side queue, you remove the risk of a client going offline between writes. The server can safely survive restarts and retry events or failures when using the queue model.

0
bibscy On

I have had the same problem and I ended up choosing to use condition Conditional Request with the Firebase REST API in order to write data transactionally. See my question and answer. Firebase: How to update multiple nodes transactionally? Swift 3 .

If you need to write concurrently (but not transactionally) to several paths, you can do that now as Firebase supports multi-path updates. https://firebase.google.com/docs/database/rest/save-data https://firebase.googleblog.com/2015/09/introducing-multi-location-updates-and_86.html