In my client code I have:
...
// 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);
}
As you an see, what I am doing is
Upload image to storage
Create a reference to this image in my firestore
Now, in my cloud function (where I check that the posted image has valid dimensions) I have:
// 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}`);
}
}
My problem is that in the client code, I create the firestore document after the image is uploaded, and this cloud functions runs just when the image is fully uploaded... So, there might be times where in this cloud function the document reference will not exist. Does anyone know how to solve this?
I am thinking to create a cloud function that is triggered when a photo is removed that deletes its document... but will have the same problem: the photo might be removed before the document is created.
And also I have thought to trigger this function only when the photo document is created, but will have problems if the client modifies my code and upload the image after the document is created.