【问题标题】:Cloud Functions, deleting Firestore SubCollections, is AdminToken necessary?Cloud Functions,删除 Firestore SubCollections,是否需要 AdminToken?
【发布时间】:2021-02-11 10:23:39
【问题描述】:

我正在尝试构建可调用的云函数,当用户删除帖子时,它也会尝试删除作为帖子的子集合的 cmets。所以我看到了示例并像文档示例一样实现了

const admin = require('firebase-admin');
const firebase_tools = require('firebase-tools');
const functions = require('firebase-functions');

admin.initializeApp({
  serviceAccountId: 'xxxxxx-xxxxx@appspot.gserviceaccount.com'
  }
);

exports.mintAdminToken = functions.https.onCall(async (data: any, context: any) => {
  const uid = data.uid;

  const token = await admin
    .auth()
    .createCustomToken(uid, { admin: true });

  return { token };
});

exports.recursiveDelete = functions
  .runWith({
    timeoutSeconds: 540,
    memory: '2GB'
  })
  .https.onCall(async (data: any, context: any) => {
    // Only allow admin users to execute this function.
    if (!(context.auth && context.auth.token && context.auth.token.admin)) {
      throw new functions.https.HttpsError(
        'permission-denied',
        'Must be an administrative user to initiate delete.'
      );
    }

    const path = data.path;
    console.log(
      `User ${context.auth.uid} has requested to delete path ${path}`
    );

    await firebase_tools.firestore
      .delete(path, {
        project: process.env.GCLOUD_PROJECT,
        recursive: true,
        yes: true,
        token: functions.config().fb.token
      });

    return {
      path: path 
    };
  });

我成功地收到了客户的自定义令牌。但我现在必须做什么?获得令牌后,我从客户端调用了“recursiveDelete”函数,但出现错误PERMISSION_DENIED

  1. 是否应该使用新的自定义管理员令牌对收到令牌的用户进行初始化? (如果我误解了,请告诉我)
  2. 在删除这样的子集合时,管理员令牌真的需要吗?它很难使用,所以我问。

【问题讨论】:

  • 我认为您根本不需要这些检查,我了解您想在帖子被删除时将其删除。只需在删除帖子时触发一个函数,将帖子 ID 传递给它,查找并删除 cmets。

标签: firebase flutter google-cloud-functions


【解决方案1】:

我不认为您真的需要针对此用例的自定义令牌,我建议您使用 firebase firestore 规则,而不是实施您自己的基于角色的身份验证。

要遵循的步骤:

1- 创建一个您可以称为“用户”的集合,并在其中包含该用户可能具有的角色字段,例如“管理员”。此集合中的每个文档 id 都可以是 firebase auth 生成的用户的 auth uid。你可以使用 currentUser 属性从你的前端获取这个 uid,这一切都解释了here

2- 使用 Firestore 规则保护您的数据库:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    // only admins can remove posts
    match /posts/{postID} {
      allow read, write: if isAdmin();
    }

    // only admins can remove comments
    match /comments/{commentID} {
      allow read, write: if isAdmin();
    }

    // this function will check if the caller has an admin role and allow or disallow the task upon that
    function isAdmin() {
      return get(/databases/$(database)/documents/
          users/$(request.auth.uid)).data.role == "ADMIN";
   }

  }
}

3- 成功删除发布文档后,您可以使用 onDelete 触发器创建一个函数,该函数会被调用并递归删除 cmets 子集合,为此您应该包含以下代码:

const client = require('firebase-tools');

exports.recursiveDelete = functions.firestore
    .document('posts/{postID}')
    .onDelete((snap, context) => {
     .....
     await client.firestore
      .delete(collectionPath, {
        project: process.env.GCLOUD_PROJECT,
        recursive: true,
        yes: true
      });
} 

【讨论】:

  • 非常感谢,但我认为您误解了,因为我想使用该云功能,因为当用户删除他们的帖子时,它也必须删除其中的子集合。并且云函数会自动删除其中的所有嵌套集合
  • 好的,我明白你想要什么。这里唯一缺少的一点是通过 mintAdminToken 将您生成的自定义令牌发送到您的客户端应用程序。然后,您的应用程序将使用此自定义令牌(如提到的 here)登录。登录后,每次调用 firebase 都将使用此自定义令牌,这样只有管理员用户才能调用您的递归函数
  • 但是如果用户已经登录怎么办?我的意思是,在上下文中,他们在登录时已经拥有自己的身份验证令牌(如谷歌身份验证)。以及如何辞职或混合令牌?和上面的问题一样,为什么 Firebase 团队在他们的官方文档中给出了所有这些复杂的方法? firebase.google.com/docs/firestore/solutions/delete-collections
猜你喜欢
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 2021-03-16
  • 1970-01-01
  • 2021-09-03
  • 2018-03-23
  • 2020-06-15
  • 1970-01-01
相关资源
最近更新 更多