在我的客户代码中,我有:
...
// 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);
}
如您所见,我在做什么
将图像上传到存储空间
在我的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文档,并且该云功能仅在图像完全上传后才运行...因此,有时在该云功能中文件参考将不存在。有人知道如何解决这个问题吗?
我正在考虑创建一个云功能,当删除照片时会触发该功能,从而删除其文档...但是会出现相同的问题:照片可能会在创建文档之前被删除。
我还考虑过仅在创建照片文档时才触发此功能,但是如果客户端修改我的代码并在创建文档后上传图像,则会出现问题。
答案 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);
}