如何在Firebase存储中使用md5控制上传?

时间:2017-05-24 16:24:06

标签: firebase firebase-storage

我想构建客户端只能上传文件一次的上传系统。

  1. 客户端将文件的md5发送到服务器。
  2. 服务器将上传路径返回给客户端。
  3. 客户端将文件上传到存储空间。
  4. 存储规则检查文件的md5是客户端之前发送的。
  5. 如何在firebase中实现它?

2 个答案:

答案 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 FunctionsStorageDatabase

有几种方法可以做到这一点,我的可能不是那么容易,但它应该让你去。

在客户端上获取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存储。