Firebase Cloud Functions - TypeError: Cannot read property 'data' of undefined when data exists

风流意气都作罢 提交于 2020-06-26 06:41:14

问题


I have the following cloud function:

exports.keepPostKeysUpdated = functions.database.ref('/posts/{postid}').onWrite(event => { 
  console.log("write on posts...");
  console.log(event.previous.params.postID);
  console.log(event.data.previous.val());
  console.log(event.data.previous.val().postID);
  var postKey = event.data.previous.val().postID;


  // When a table, category, or region is changed the old upload has to be deleted
  if (event.data.previous.exists()) {
    if (event.data.previous.val().table != event.data.val().table || event.data.previous.val().region != 
        event.data.val().region || event.previous.data.val().category != event.data.val().category) {
          // category, region, or table was changed
          console.log(postKey);
          if (event.data.previous.val().table != event.data.val().table) {
            console.log("Table was changed");
            // delete the post from the old table
            const oldTable = event.data.previous.val().table;
            const newTable = event.data.val().table;

            addToNewTable(newTable, postKey);
            removePostFromOldTable(oldTable, postKey);
          }
          if (event.data.previous.val().category != event.data.val().category) {
            console.log("Category was changed");
            // delete the post from the old category
            const oldCategory = event.data.previous.val().category;
            const newCategory = event.data.val().category;

            addToNewCategory(newCategory, postKey);
            removePostFromOldCategory(oldCategory, postKey);
          }
          if (event.data.previous.val().region != event.data.val().region) {
            console.log("Region was changed");
            // delete post from old region
            const oldRegion = event.data.previous.val().region;
            const newRegion = event.data.val().region;

            addToNewRegion(newRegion, postKey);
            removePostFromOldRegion(oldRegion, postKey);
          }  
        }
        else {
          return
        }
}
else {
  // previous value does not exist this case is handled by 
  // copyPostKey
  return
}
});

It work perfectly fine when a table or region is changed but fails every time a category is changed. The error is coming from the line var postKey = event.data.previous.val().postID; How can this value be read some times but not others? I can even console log the key, but it says it can't be read when I try to assign it to postKey. Any idea what this issue is from?

The data is always written the same way from my iOS app

ref.child("posts").child(editedPost.postID).updateChildValues(["table": editedPost.table])
ref.child("posts").child(editedPost.postID).updateChildValues(["category": editedPost.category])
ref.child("posts").child(editedPost.postID).updateChildValues(["region": editedPost.region])

node = v6.11.2 firebase-tools = 3.10.10


回答1:


In addition to Matts answer, you need to adjust your logic.

exports.keepPostKeysUpdated = functions.database.ref('/posts/{postid}').onWrite(event => { 
  // When a table, category, or region is changed the old upload has to be deleted
  if (event.data.previous.exists()) {
      var postKey = event.data.previous.val().postID;

If you check the postKey after the event.data.previous.exists() statement you shouldn't have any problems.

It might be worth looking at the Firebase Documentation, they have different triggers depending on the write operation;

onWrite(), which triggers when data is created, destroyed, or changed in the Realtime Database.

onCreate(), which triggers when new data is created in the Realtime Database.

onUpdate(), which triggers when data is updated in the Realtime Database.

onDelete(), which triggers when data is deleted from the Realtime Database.

In your case, you could change your logic to use onUpdate

exports.keepPostKeysUpdated = functions.database.ref('/posts/{postid}').onUpdate(event => { 
  var currentValue = currentValue;
  var previousValue = previousValue;
  var postKey = previousValue.postID;


  // When a table, category, or region is changed the old upload has to be deleted
    if (previousValue.table != currentValue.table || previousValue.region != currentValue.region || event.previous.data.val().category != currentValue.category) {
      // category, region, or table was changed
      console.log(postKey);
      if (previousValue.table != currentValue.table) {
        console.log("Table was changed");
        // delete the post from the old table
        const oldTable = previousValue.table;
        const newTable = currentValue.table;

        addToNewTable(newTable, postKey);
        removePostFromOldTable(oldTable, postKey);
      }
      if (previousValue.category != currentValue.category) {
        console.log("Category was changed");
        // delete the post from the old category
        const oldCategory = previousValue.category;
        const newCategory = currentValue.category;

        addToNewCategory(newCategory, postKey);
        removePostFromOldCategory(oldCategory, postKey);
      }
      if (previousValue.region != currentValue.region) {
        console.log("Region was changed");
        // delete post from old region
        const oldRegion = previousValue.region;
        const newRegion = currentValue.region;

        addToNewRegion(newRegion, postKey);
        removePostFromOldRegion(oldRegion, postKey);
      }  
    } else {
      return
    }
});



回答2:


previous.val() only works if the previous value exists. It may not exist if this is the first write for that path. You should check to see if it exists before referencing it:

event.data.previous.exists()

https://firebase.google.com/docs/database/extend-with-functions#reading_the_previous_value



来源:https://stackoverflow.com/questions/46063941/firebase-cloud-functions-typeerror-cannot-read-property-data-of-undefined-w

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!