Firestore delete all user data on account delete using a Firebase Function

Deadly 提交于 2019-12-21 22:35:31

问题


I'm new to Firebase/Firestore and trying to create a Firebase Function that will delete all user data upon deletion of an Auth account.

My functions is successfully called on deleting an account and I'm trying to delete a collection called links for that user and then delete the user document. But I'm getting an error of linksRef.forEach is not a function.

Any guidance on how I'd do this cascading delete?

exports.deleteUserData = functions.auth.user().onDelete((event) => {
  const userId = event.data.uid;

  const store = admin.firestore();

  store.collection('users').doc(userId).get().then(user => {
    if (user.exists) {

      user.collection('links').get().then(links => {
        links.forEach(link => {
          link.delete();
        })
        return;
      }).catch(reason => {
        console.log(reason);
      });

      user.delete();
      return;

    }    
    else {
      // User does not exist
      return;
    }
  }
  ).catch(reason => {
    console.log(reason);
  });  
});

回答1:


Based on the comment from @Doug Stevenson regarding Promises I managed to get this working by scraping together code. Definitely not the cleanest but it works if anyone is trying to do similar.

// Delete user data when user deleted
exports.deleteUserData = functions.auth.user().onDelete((event) => {
  const userId = event.data.uid;

  const database = admin.firestore();

  const linksRef = database.collection('users').doc(userId).collection('links');

  const deleteLinks = deleteCollection(database, linksRef, BATCH_SIZE)

  return Promise.all([deleteLinks]).then(() => {
    return database.collection('users').doc(userId).delete();
  });

});

/**
 * Delete a collection, in batches of batchSize. Note that this does
 * not recursively delete subcollections of documents in the collection
 */
 function deleteCollection (db, collectionRef, batchSize) {
  var query = collectionRef.orderBy('__name__').limit(batchSize)

  return new Promise(function (resolve, reject) {
    deleteQueryBatch(db, query, batchSize, resolve, reject)
  })
}

function deleteQueryBatch (db, query, batchSize, resolve, reject) {
  query.get()
  .then((snapshot) => {
          // When there are no documents left, we are done
          if (snapshot.size === 0) {
            return 0
          }

        // Delete documents in a batch
        var batch = db.batch()
        snapshot.docs.forEach(function (doc) {
          batch.delete(doc.ref)
        })

        return batch.commit().then(function () {
          return snapshot.size
        })
      }).then(function (numDeleted) {
        if (numDeleted <= batchSize) {
          resolve()
          return
        }
        else {
        // Recurse on the next process tick, to avoid
        // exploding the stack.
        return process.nextTick(function () {
          deleteQueryBatch(db, query, batchSize, resolve, reject)
        })
      }
    })
      .catch(reject)
    }



回答2:


Based on this official doc from Firebase, it seems that it's quite easy to set-up a clearData function.

It only supports basic Firestore structure. But in your case it should work configuring only the user_privacy.json with something like:

{
  "firestore": {
    "clearData": [
      {"collection": "users", "doc": "UID_VARIABLE", "field": "links"},
      {"collection": "users", "doc": "UID_VARIABLE"}
    ],
  }
}

For more complex cases, the function code needs to be tweaked.

Please refer to the doc



来源:https://stackoverflow.com/questions/49367260/firestore-delete-all-user-data-on-account-delete-using-a-firebase-function

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