Issue using Cloud Functions to sync realtime database with Firestore

Viewed 62

I'm using an extremely simple Cloud Function to (try to) keep my realtime database in sync with the Firestore.

exports.copyDocument = functions.database.ref('/invoices/{companyId}/{documentId}')
    .onWrite((change, context) => {
        if (!change.after.exists()) {
            return null;
        }
        return admin.firestore().collection('companies').doc(context.params.companyId).collection('invoices')
            .doc(context.params.documentId)
            .set(change.after.val());
    });

Unfortunately, I am seeing issues where sometimes the Cloud Firestore document does not have the latest copy of the realtime DB data. It's infrequent, but nonetheless impacting my end users.

Why is this happening?

Two ideas I had were -

  1. The Firestore is possibly unavailable to write to in the Cloud Function, and I don't have retries enabled in my Cloud Function, so it could just be erroring out. Enabling retries will solve my problem. However, I have absolutely 0 error logs of this happening.

  2. User makes change A, then user makes change B 2-3 seconds later. In this case, it's possible, I guess, that the Cloud Function trigger for change A hasn't executed, but the trigger for change B quickly executes, then the change A trigger executes and copies 'stale' data. Possible remedies would be to fetch the latest version again from the realtime database in my Cloud Function (not ideal, it's nice using change.after.val()), or perhaps keep some incrementing integer on my document, and instead copy it to the Firestore using a transaction that compares versions instead of a simple set().

  3. The only error message I do see in my Cloud Function error logs is:

The request was aborted because there was no available instance. Additional troubleshooting documentation can be found at: https://cloud.google.com/functions/docs/troubleshooting#scalability

But those docs indicate that this error is always retried, even without explicitly enabling function retries.

I am leaning towards issue 1 - the Firestore just 'blips' sometimes, retries aren't enabled, and I'm not logging the failed promise properly. If this is the case - how can I fix this logging?

0 Answers
Related