Firebase Storage 使用介绍

发布时间 2024-01-08 17:04:10作者: BuckyI

之前使用 Firebase 还有 streamlit 创建了个个人项目,想用其中的对象存储功能,翻了翻 Firebase 的 Cloud Storage 文档,没有 Python 的介绍。
不过好在文档中提到 Storage 基于 Google Cloud Storage,可以通过 Google Cloud Storage API 执行服务器端处理,遂研究了一下 Firebase 中 Storage 如何使用 Python 在服务器端进行操作。

Cloud Storage for Firebase 将您的文件存储在某个 Google Cloud Storage 存储桶中

基本配置

安装依赖库

pip install --upgrade google-cloud-storage

配置服务密钥
Firebase 项目的基本配置阶段,会生成一个服务密钥(json 格式的文件)用于验证,这里不过多介绍。

Storage 部分可以看到 Firebase 项目对应的存储桶位置。需要注意,我们使用 Google Cloud Storage API 进行操作,但是上面获得的服务密钥是没有创建 bucket 的权限的,只能对于这个项目 bucket 进行管理!

获取到 bucket 名称后,可以用下面简单的代码进行验证:

from google.cloud import storage

key_dict = XXX

storage_client = storage.Client.from_service_account_info(key_dict)

list(storage_client.list_buckets())

storage_client.bucket("<project-name>.appspot.com").blob(
    "hello.txt"
).upload_from_string("Hello, World! ")

一些常用操作

因为不涉及 bucket 的操作,主要参考 Cloud Storage 中介绍的上传和下载方法进行实现。

bucket = storage_client.bucket("<project-name>.appspot.com")
关于文件命名规则

如果您在存储桶 your-bucket 中创建名为 folder1/file.txt 的对象,则该对象的路径为 your-bucket/folder1/file.txt,且 Cloud Storage 未在其中存储名为 folder1 的文件夹。从 Cloud Storage 的角度来看,字符串 folder1/ 是该对象的名称的一部分。但是,由于该对象的名称中包含 /,因此某些工具会实现文件夹的外观。

下载
# download
blob = bucket.blob("hello.txt")
contents = blob.download_as_string() # 下载到内存
blob.download_to_filename("hello_local.txt") # 下载到文件
上传
blob = bucket.blob("hello.txt")

# Optional: set a generation-match precondition to avoid potential race conditions and data corruptions.
# The request to upload is aborted if the object's generation number does not match your precondition.
# 目标对象还不存在时,设置 if_generation_match 为 0.
# 目标对象已存在于 bucket 时, 设置为它的 generation number.
precondition = 0  # 假定目标不存在
blob.upload_from_filename("hello_local.txt", if_generation_match=precondition)

blob.upload_from_string("Hello world!")

对象存在 generation 还有 metageneration 属性,具体可参见这里,相当于文件的 id,每次更新都会刷新。上传时,通过额外的选项 if_generation_match 进行指定,可以避免冲突的发生(例如已经上传成功了,又上传了一遍)。

查看 blob: 列出对象,查看对象元数据

列出对象  |  Cloud Storage  |  Google Cloud

for blob in bucket.list_blobs():
    print(blob.name)

for blob in bucket.list_blobs(prefix="test"):
    print(blob.name)

查看和修改对象元数据  |  Cloud Storage  |  Google Cloud

metageneration_match_precondition = blob.metageneration

metadata = {'color': 'Red', 'name': 'Test'}
blob.metadata = metadata
blob.patch(if_metageneration_match=metageneration_match_precondition)
删除对象
blob.reload()  # Fetch blob metadata to use in generation_match_precondition.
generation_match_precondition = blob.generation

blob.delete(if_generation_match=generation_match_precondition)