我想构建客户端只能上传文件一次的上传系统。
如何在firebase中实现它?
答案 0 :(得分:1)
我用两种方式解释这个问题:
您可以完全在Storage security rules中执行这两项操作:
// Don't allow overwrites
service firebase.storage {
match /b/{bucket}/o {
match /files/{fileName} {
// Allow an initial upload, or a metadata change
allow write: if resource == null
|| request.resource.md5Hash == resource.md5Hash;
}
}
}
// Hash files so you only have one file
service firebase.storage {
match /b/{bucket}/o {
match /files/{fileHash} {
// Allow initial upload only, ensure that the hashes match
allow write: if resource == null
&& request.resource.md5Hash == fileHash;
}
}
}
答案 1 :(得分:0)
这就是我这样做的方式:
我会使用Firebase Functions,Storage和Database。
有几种方法可以做到这一点,我的可能不是那么容易,但它应该让你去。
在客户端上获取MD5哈希值。
将MD5哈希写入数据库,使其类似于/requests/{md5Hash}
您的函数为该端点提供了onWrite()
事件侦听器。
该函数在另一个端点中查找md5Hash,该端点在/files/{md5Hash}
等端点中完全锁定(对外界没有读写访问权限)。
(下面用“自由手”写,所以可能会有一些错误,但你明白了)
module.exports = functions.database.ref('requests/{userId}/{md5Hash}')
.onWrite(event => {
//Only respond to new writes
if (!event.data.val() || event.data.previous.val()) {
return null
}
const {userId, md5Hash} = event.params;
ref.child('files').child(userId).once('value')
.then(snapshot => {
return snapshot.hasChild(md5Hash)
})
.then(exists => {
//If the md5Hash doesn't already exist
var obj = {};
if (!exists) {
obj['status'] = 'permitted'
//This will be the path for Storage
obj['path'] = `files/${userId}/${md5Hash}`
} else {
obj['status'] = 'denied'
}
return event.data.ref.update(status)
})
.catch(error => {
console.log(error);
})
})
当这种情况发生时,您可以让您的客户端收听您的/request/{md5Hash}
端点。在此端点中,您可以拥有一个表示操作状态的状态键。如果云功能检测到md5哈希已存在,则会写入/requests/{md5Hash}/status = denied
,否则会写/requests/{md5Hash}/status = permitted
。\
然后,您可以在云功能中为您的文件创建一个路径,该路径将包含不同的参数,例如const path = ${userId}/${files}/${md5Hash}
然后将该路径写入/requests/{md5Hash}/path
= yourPath
。
然后使用函数指定的路径将对象上传到Firebase存储。