Firestore 使用 Firebase 函数删除帐户删除时的所有用户数据

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

我是 Firebase/Firestore 的新手,正在尝试创建一个 Firebase 函数,该函数将在删除 Auth 帐户时删除所有用户数据。

我的函数在删除帐户时成功调用,我正在尝试删除该用户的名为链接的集合,然后删除用户文档。但是我收到 linksRef.forEach is not a function.

的错误

关于如何执行此级联删除的任何指导?

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);
  });  
});

根据@Doug Stevenson 关于 Promises 的评论,我设法通过拼凑代码来实现它。绝对不是最干净的,但如果有人试图做类似的事情,它会起作用。

// 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)
    }

基于来自 Firebase 的this official doc,似乎很容易设置一个clearData函数。

它只支持基本的 Firestore 结构。但在你的情况下,它应该只配置 user_privacy.json 类似的东西:

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

对于更复杂的情况,需要调整函数代码。

请参考the doc