【发布时间】:2017-05-27 02:26:01
【问题描述】:
我想搭建一个客户端只能上传一次文件的上传系统。
- 客户端将文件的 md5 发送到服务器。
- 服务器返回上传路径给客户端。
- 客户端上传文件到存储。
- 存储规则检查文件的 md5 是否是客户端之前发送的。
如何在 firebase 中实现这一点?
【问题讨论】:
-
什么标识文件?即这个文件和这个文件有什么区别?
我想搭建一个客户端只能上传一次文件的上传系统。
如何在 firebase 中实现这一点?
【问题讨论】:
我对这个问题有两种解释:
您可以完全在 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;
}
}
}
【讨论】:
我会这样做:
我会使用 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 存储。
【讨论】: