Aimn Blbol
Aimn Blbol

Reputation: 1285

While using Firebase emulator, FireStore transaction triggers cloud function (onDocumentUpdated) when it is not supposed to

In my project, I am using FireStore, Cloud Functions, and Firebase emulator in the backend while using Flutter in the backend. I have a transaction that reads a profile document and then uses the profile data to create two relationship documents.

When running the code, I noticed that the cloud function onUpdateProfile was triggered, meaning the profile document was updated. But I did not update the profile document I only read it inside the transaction. This is what I see in the logs of the Firebase emulator.

i  functions: Beginning execution of "us-east4-onCreateRelationship"
i  functions: Finished "us-east4-onCreateRelationship" in 2.332654ms
i  functions: Beginning execution of "us-east4-onCreateRelationship"
i  functions: Finished "us-east4-onCreateRelationship" in 371.116441ms
i  functions: Beginning execution of "us-east4-onUpdateProfile". <----------
i  functions: Finished "us-east4-onUpdateProfile" in 2.047866ms  <----------

Why was the profile doc updated even though I never updated it?

Here is my Flutter code that shows the transaction:

await _firestore.runTransaction((transaction) async {
  // read the profile first inside the transaction.
  // notice that I am not updating the profile
  final docSnapshot =
      await transaction.get(_firestore.doc('/users/$id'));
  final profile = docSnapshot.data();

  if (profile != null) {
    // get whatever you want from the profile
    final pName = profile['name'] as String;

    // create two relationship docs
    transaction
      ..set(_firestore.doc('/users/$uid/relationships/$pid'), {
        'authorId': uid,
        'pName': pName
         // place your properties.  I am simplifying the doc
      })
      ..set(_firestore.doc('/users/$pid/relationships/$uid'), {
        'authorId': uid,
        'pName': myProfile.name
         // place your properties.  I am simplifying the doc
      });
  }
});

I changed my transaction to a batch like this:

This time the profile doc was not updated.

Here is my Flutter code that shows the batch

// read the profile doc first from firestore
final docSnapshot = await _firestore
  .doc('/users/$pid')
  .withConverter<MyProfile>(
    fromFirestore: MyProfile.fromFirestore,
    toFirestore: (myProfile, _) => myProfile.toFirestore(),
  )
  .get();
final profile = docSnapshot.data();

// create two relationship docs using a batch
final batch = _firestore.batch()
..set(_firestore.doc('/users/$uid/relationships/$pid'), {
  'authorId': uid,
  'pName': profile.name,
  // place your properties.  I am simplifying the doc
})
..set(_firestore.doc('/users/$pid/relationships/$uid'), {
  'authorId': uid,
  'pName': myProfile.name,
  // place your properties.  I am simplifying the doc
});

await batch.commit();

Upvotes: 0

Views: 54

Answers (0)

Related Questions