FIrebase云功能(删除Firestore文档)

时间:2020-07-05 05:44:35

标签: firebase google-cloud-firestore google-cloud-functions firebase-storage firebase-security

在我的客户代码中,我有:

...
// Upload image to storage
const task = storageRef.put(blob);
...
// When the image is fully uploaded to the storage...
task.then(async () => {
   ...
     await firebase
       .getDatabase()
       .collection("posts")
       .doc(userId)
       .collection("userPosts")
       .add(data);
}

如您所见,我在做什么

  1. 将图像上传到存储空间

  2. 在我的Firestore中创建对此图像的引用

现在,在我的云功能(我检查发布的图像具有有效尺寸)中,我有:

// Create Google Cloud Storage
const gcs = new Storage();

// Create Google Cloud Firestore
const gcf = new Firestore();

// Validate image dimensions
exports.validateImageDimensions = functions
  .region("us-central1")
  // Increased memory, increased timeout (compared to defaults)
  .runWith({ memory: "2GB", timeoutSeconds: 540 })
  .storage.object()
  .onFinalize(async (object) => {
    // Get the bucket which contains the image
    const bucket = gcs.bucket(object.bucket);
    
    ...

    // Get the file id
    const fileId = file.id

       ...

         // Remove the files that are not images, or whose dimensions are not valid
          if (!isImage || !hasValidDimensions) {
            try {
              // Get post's owner (⚠️ Be aware that clients can choose whatever metadata that they add!!)
              const metadata = await file.getMetadata();
              const {
                metadata: { owner },
              } = metadata[0];

              await bucket.file(filePath).delete();

              console.log(
                `The image ${filePath} has been deleted because it has invalid dimensions.
                 This may be an attempt to break the security of the app made by the user ${owner}`
              );

              // Delete the firestore photo's document
              gcf
                .collection("posts")
                .doc("owner")
                .collection("userPosts")
                .doc(fileId)
                .delete()
                .catch((err) => {
                  console.log(
                    `Error deleting the document 'posts/${owner}/userPosts/${fileId}': ${err}`
                  );
                });
            } catch (err) {
              console.log(`Error deleting invalid file ${filePath}: ${err}`);
            }
          }

我的问题是,在客户端代码中,我在图像上传后创建了Firestore文档,并且该云功能仅在图像完全上传后才运行...因此,有时在该云功能中文件参考将不存在。有人知道如何解决这个问题吗?

我正在考虑创建一个云功能,当删除照片时会触发该功能,从而删除其文档...但是会出现相同的问题:照片可能会在创建文档之前被删除。

我还考虑过仅在创建照片文档时才触发此功能,但是如果客户端修改我的代码并在创建文档后上传图像,则会出现问题。

1 个答案:

答案 0 :(得分:2)

您为什么不从客户端调用Cloud Function而不使用存储触发器?您可以在存储上传完成后调用它。

// Upload image to storage
const task = storageRef.put(blob);
...
// When the image is fully uploaded to the storage...
task.then(async () => {
   // Call the Cloud Function to verify the image
   callcloudfunction(storagepath)
   .then((isvalid) => {
     if(isvalid) {
       ...
       await firebase
         .getDatabase()
         .collection("posts")
         .doc(userId)
         .collection("userPosts")
         .add(data);
     }
   })
}

编辑:如果要防止黑客绕过云功能的检查,请更改规则以防止在userPosts中创建任何文档,并将文档直接添加到云功能中:

// Upload image to storage
const task = storageRef.put(blob);
...
// When the image is fully uploaded to the storage...
task.then(async () => {
   // Call the Cloud Function to verify the image and create the document
   callcloudfunction(storagepath, userId, data);
}