Search code examples
node.jsfirebase-realtime-databasegoogle-cloud-functionsfirebase-admin

In firebase cloud function the child is self-deleting


When I add a transaction in the function below, the child of the "guncelLig" is automatically deleted. When I remove the second transaction there is no problem, it works very well.

this code work correct :

    for (let i = 0; i < users.length; i++) {
      const userID = users[i].id;
      database.ref().child("users").child("profilData").child(userID).child("guncelLig").transaction(function (value) {
        if (value > 1) {
          database.ref().child("users").child("profilData").child(userID).update({
            "lastUpdate": toSwiftDate(),
          });
          return value - 1; 
        }
    
        return value;
      });

}

but when I add the new part to the code below, "guncelLig" is completely deleted from the firebase realtime databse:

    for (let i = 0; i < users.length; i++) {
      const userID = users[i].id;

   database.ref().child("users").child("profilData").child(userID).child("guncelLig").transaction(function (value) {
        if (value > 1) {
          database.ref().child("users").child("profilData").child(userID).update({
            "lastUpdate": toSwiftDate(),
          });

          /// NEW CODE ERROR SOURCHE
database.ref().child("users").child("profilData").child(userID).child("EnYukselLig").transaction(function (EnYukselLig) {
            if (EnYukselLig > value - 1) {
              return value - 1;
            }
            return EnYukselLig;
          });

          return value - 1; // arttır
        }
        return value; /// ALWAYS RETURN NULL
      });
    }

Where am I doing wrong? please help me


Solution

  • You should write your code as async/await. With await you can wait for the nested transaction to finish.

    for (let i = 0; i < users.length; i++) {
      const userID = users[i].id;
      database
        .ref()
        .child("users")
        .child("profilData")
        .child(userID)
        .child("guncelLig")
        .transaction(async (value) => {
          if (value > 1) {
            await database
              .ref()
              .child("users")
              .child("profilData")
              .child(userID)
              .update({
                lastUpdate: toSwiftDate(),
              });
    
            /// NEW CODE ERROR SOURCHE
            await database
              .ref()
              .child("users")
              .child("profilData")
              .child(userID)
              .child("EnYukselLig")
              .transaction(function (EnYukselLig) {
                if (EnYukselLig > value - 1) {
                  return value - 1;
                }
                return EnYukselLig;
              });
    
            return value - 1; // arttır
          }
          // No handler if the value is NULL
          return value; /// ALWAYS RETURN NULL
        });
    }
    

    You also don't handle the case if value is already null.

    It is not recommmended to nest transactions like that. Transacions by nature can run multiple times and there is no guaranty that they finish as expected depending on the amount of updates that happen on the same location.