Firebase是一个流行的Backend as a Service (BaaS)平台,由Google提供。它旨在通过提供多种服务,如认证、实时数据库、Firestore(NoSQL数据库)、云函数、机器学习、云存储等,来替代传统的后端服务器。这些服务都是基于云的,并且是生产就绪的,可以根据需求自动扩展,无需任何配置。
在之前的文章中,介绍了Google Firestore,这是Firebase提供的基于云的NoSQL数据库。可以在这里阅读之前关于Google Firestore的文章。Firebase提供的另一个服务是Cloud Storage,这是一个功能强大但简单的存储服务。
Firebase中的Cloud Storage是基于Google Cloud Platform (GCP)的Google云存储。免费层版本为存储桶提供5GB的存储空间。在本文中,将学习关于云存储的知识,以及如何使用Python安全地通过互联网存储和访问文件。
要访问Cloud Storage,必须创建一个Firebase项目。让创建一个新的Firebase项目。在浏览器中打开Firebase,使用Google账户登录,然后点击“创建一个新项目”,这将要求输入项目名称。可以给Firebase项目起任何名字,将其命名为“cloud-storage-basics-python”。点击左侧导航栏中的“Storage”。
点击“开始使用”按钮后,系统会提示选择生产模式或测试模式。选择测试模式并继续。
系统会提示选择云存储桶的位置。选择离当前位置最近的区域以减少延迟,然后点击完成。
要连接到Google Firestore,需要安装一个名为“firebase-admin”的Python包。这可以像安装任何其他Python包一样使用pip安装。
确保Python版本是3.6或以下,因为从Python 3.7开始添加的async模块会导致这个模块抛出异常。
如果安装了更高版本的Python,可以使用anaconda创建一个带有Python 3.6的新环境。运行以下命令在anaconda中创建并激活新环境。
conda create -n cloud_storage_env python=3.6.5
conda activate cloud_storage_env
要安装“firebase-admin”包,请运行以下命令。
pip install firebase-admin
要使用Firebase提供的任何服务,首先需要使用凭据进行身份验证。要获取用于身份验证的凭据,请单击项目设置和“服务帐户”。
在“服务帐户”选项卡中,可以找到连接到Google Firebase的代码片段。选择Python作为语言并复制代码片段。复制代码片段后,单击“管理服务帐户权限”。
现在单击“管理密钥”,然后单击“添加密钥”按钮并选择JSON作为文件格式,然后点击创建。
现在已经拥有了凭据,让连接到Firebase并开始访问云存储服务。为此,请粘贴以下代码片段,并添加在上一步中下载的凭据文件的文件路径。可以在Firebase云存储控制台中找到存储桶链接。
import firebase_admin
from firebase_admin import credentials, storage
cred = credentials.Certificate("path/to/your/credentials.json")
firebase_admin.initialize_app(cred, {'storageBucket': 'your_bucket_link_without_gs://'}) # 连接到firebase
现在已经连接到Firebase,让尝试使用云存储服务。
现在假设在服务器上维护了一个文件夹结构,并希望在存储桶中复制相同的文件夹结构。为此,可以直接使用“upload_from_filename()”函数,这是blob对象的一个属性。这个函数将复制每个上传文件的文件夹结构。这意味着,如果有一个名为“text_files”的文件夹中的文本文件,相同的文件夹结构也将在存储桶中被复制。现在,让看看如何使用这个函数将文件上传到存储桶。
首先,将上传一个位于根目录中的图像文件到存储桶。完成后,将尝试上传一个位于名为“text_docs”的文件夹中的文本文件到存储桶,使用上述描述的函数。
file_path = "sample_image_file.jpg"
bucket = storage.bucket() # 存储桶
blob = bucket.blob(file_path)
blob.upload_from_filename(file_path)
可以看到图像文件已经被上传到存储桶的根目录。现在让尝试上传位于“text_docs目录”中的文本文件。
file_path = "text_docs/sample_text_file.txt"
bucket = storage.bucket() # 存储桶
blob = bucket.blob(file_path)
blob.upload_from_filename(file_path)
可以看到文本文件已经被上传到text_docs文件夹中,就像它在本地机器上一样。
现在假设不在服务器上维护文件夹结构,但希望在存储桶中维护一个适当的文件夹结构。为此,也可以使用方法“upload_from_filename()”,但稍作修改。让尝试将图像文件上传到名为“images”的文件夹中。在本地机器上,图像文件位于根目录,没有名为images的文件夹。还将重命名图像文件,同时将其存储在存储桶中。
from google.cloud import storage
from google.oauth2 import service_account
def upload_blob(bucket_name, source_file_name, destination_blob_name):
credentials = service_account.Credentials.from_service_account_file("path/to/your/credentials.json")
storage_client = storage.Client(credentials=credentials)
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(destination_blob_name)
blob.upload_from_filename(source_file_name)
print(f"File {source_file_name} uploaded to {destination_blob_name}.")
upload_blob(firebase_admin.storage.bucket().name, 'sample_image_file.jpg', 'images/beautiful_picture.jpg')
现在让看看根目录中的图像是否已经被上传到存储桶中的名为“images”的文件夹中。可以看到一个新的名为“images”的文件夹已经被创建,图像文件也被上传到了该文件夹中。
现在,如果想从存储桶中访问文件并下载它们,可以用几行代码轻松完成。让尝试下载上传到存储桶中的位于text_docs文件夹中的文本文件,并将文件重命名为“downloaded_file.txt”。以下代码片段将文件下载到本地机器。
credentials = service_account.Credentials.from_service_account_file("path/to/your/credentials.json")
storage.Client(credentials=credentials).bucket(firebase_admin.storage.bucket().name).blob('text_docs/sample_text_file.txt').download_to_filename('downloaded_file.txt')
credentials = service_account.Credentials.from_service_account_file("path/to/your/credentials.json")
files = storage.Client(credentials=credentials).list_blobs(firebase_admin.storage.bucket().name) # 获取存储桶中的所有文件
for i in files: print('The public url is ', i.public_url)