我正在构建一个Android应用,需要我为用户存储一些图片。
假设我有2个用户:A和B.他们应该能够读取/写入他们的特定文件夹:用户A可以读取和写入桶/ images / userA,用户B可以读取和写入桶/图像/用户B。他们不应该有其他任何东西。
现在让我们说用户A上传了picture1.jpg和picture2.jpg。用户A如何向用户B授予对bucket / images / userA / picture1.jpg的访问权限?用户B不应该访问picture2.jpg。
我正在寻找可以为许多用户扩展的解决方案(~100.00 +)。我想每次我想要访问文件时,都要在存储规则中添加规则,这不是一个好主意。
我现在使用的解决方案是任何登录的人都可以阅读任何内容,如果他们有完整的路径。路径不容易猜到,当我想提供访问时,我提供了链接。这是一个安全的解决方案吗?我不这么认为。
答案 0 :(得分:0)
你可以use custom File Metadata。它的作用是为文件的元数据添加Map<String, String>
。由于Map中的键是唯一的,因此您可以将用户B的id存储为键,并使用空字符串作为值:
StorageMetadata metadata = new StorageMetadata.Builder()
.setCustomMetadata(userId,"") //User B's id
.build();
然后使用updateMetadata()
方法共享文件:
picture1Ref.updateMetadata(metadata)
.addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
@Override
public void onSuccess(StorageMetadata storageMetadata) {
// Updated metadata is in storageMetadata
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Uh-oh, an error occurred!
}
});
然后,为了在Firebase端进行验证,您可以将规则设置如下:
service firebase.storage {
match /b/{bucket}/o {
match /images/{userId}/{pictureName}{
allow write: if request.auth.uid == userId;
allow read: if request.auth.uid == userId || request.auth.uid in resource.metadata.keys();
}
}
}
如果您想与更多用户共享同一个文件(假设用户C和D),您可以重复将其ID传递给自定义元数据的相同步骤,因为只更新元数据中指定的属性以及所有其他属性没有修改。
如果要撤消特定用户的访问权限,可以为自定义元数据设置空值,然后再次调用updateMetadata()
。
StorageMetadata metadata = new StorageMetadata.Builder()
.setCustomMetadata(userId, null)
.build();