1 Firestore
1.1 Firestore 和 Realtime Database
Realtime Database | Cloud Firestore | |
---|---|---|
数据模式 | Json 树 | 文档与集合 |
离线数据支持 | 安卓、苹果 | 安卓、苹果、Web 客户端 |
在线监测 | 支持 | 不提供原生支持 |
数据查询 | 具有有限排序和过滤功能的深度查询 | 具有复合排序和过滤的索引查询 |
可扩展性 | 缩放需要分片 | 缩放是自动的 |
收费 | 仅对带宽和存储收费,但费率更高 | 主要对**(读、写、删除)操作**收费,并以较低的费率对带宽和存储收费。 |
1.2 如何在 Unity 中使用 Firestore
- 创建数据库并在 Unity 项目中集成 SDK
- 初始化 Cloud Firestore
using Firebase.Firestore;
using Firebase.Extensions;
FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
- 添加数据
使用以下示例代码创建一个新集合和一个文档。
DocumentReference docRef = db.Collection("users").Document("alovelace");
Dictionary<string, object> user = new Dictionary<string, object>
{
{ "First", "Ada" },
{ "Last", "Lovelace" },
{ "Born", 1815 },
};
docRef.SetAsync(user).ContinueWithOnMainThread(task => {
Debug.Log("Added data to the alovelace document in the users collection.");
});
现在将另一个文档添加到
users
集合中。请注意,此文档包含一个未出现在第一个文档中的键值对(中间名)。集合中的文档可以包含不同的信息集。
DocumentReference docRef = db.Collection("users").Document("aturing");
Dictionary<string, object> user = new Dictionary<string, object>
{
{ "First", "Alan" },
{ "Middle", "Mathison" },
{ "Last", "Turing" },
{ "Born", 1912 }
};
docRef.SetAsync(user).ContinueWithOnMainThread(task => {
Debug.Log("Added data to the aturing document in the users collection.");
});
- 读取数据
可以使用“get”方法来检索整个集合。
CollectionReference usersRef = db.Collection("users");
usersRef.GetSnapshotAsync().ContinueWithOnMainThread(task =>
{
QuerySnapshot snapshot = task.Result;
foreach (DocumentSnapshot document in snapshot.Documents)
{
Debug.Log(String.Format("User: {0}", document.Id));
Dictionary<string, object> documentDictionary = document.ToDictionary();
Debug.Log(String.Format("First: {0}", documentDictionary["First"]));
if (documentDictionary.ContainsKey("Middle"))
{
Debug.Log(String.Format("Middle: {0}", documentDictionary["Middle"]));
}
Debug.Log(String.Format("Last: {0}", documentDictionary["Last"]));
Debug.Log(String.Format("Born: {0}", documentDictionary["Born"]));
}
Debug.Log("Read all data from the users collection.");
});
- 保护数据
可以在控制台的 规则选项卡 中修改您的安全规则。
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
2 Cloud Functions
2.1 Cloud Functions 简介
Cloud Functions for Firebase 是一个无服务器框架,可让您自动运行后端代码以响应由 Firebase 功能和 HTTPS 请求触发的事件。您的 JavaScript 或 TypeScript 代码存储在 Google 的云中并在托管环境中运行。无需管理和扩展您自己的服务器。
- 关键能力
- 集成 Firebase 平台
- 零维护
- 私密性与安全性
- 触发方式
-
HTTP 请求触发
可以通过 Http 请求触发 Function 实现诸如时间服务器、数据库搜索等功能。
-
Firebase 各类触发器触发
通过各类 Firebase 的触发器触发函数,可以实现数据库部分字段的数值统计等功能,避免各个客户端单独执行写入操作造成的数据混乱。触发器有注入 Cloud Firestore 触发器、Authentication 触发器等。
-
定时触发函数
-
在应用中直接调用函数
-
2.2 编写、测试、部署 Cloud Functions
- 设置 Node.js 和 Firebase CLI
Cloud Functions 支持 JavaScript 和 TypeScript,这里我们使用 JavaScript。
需要一个 Node.js 环境来编写函数,并且需要 Firebase CLI 将函数部署到 Cloud Functions。
安装 Node.js 和 npm 后,通过 npm 安装 CLI。
npm install -g firebase-tools
- 初始化项目
- 运行
firebase login
以通过浏览器登录并验证 Firebase CLI。- 转到您的 Firebase 项目目录。
- 运行
firebase init firestore
。- 运行
firebase init functions
。
- 编写函数代码
使用 Node
require
语句导入 Cloud Functions 和 Admin SDK 模块。这些行加载
firebase-functions
和firebase-admin
模块,并初始化一个可以从中进行 Cloud Firestore 更改的admin
应用程序实例。只要 Admin SDK 支持可用,例如 FCM、身份验证和 Firebase 实时数据库,它就提供了一种使用 Cloud Functions 集成 Firebase 的强大方法。
// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
对于
addMessage()
函数,将这些行添加到index.js
:
addMessage()
函数是一个 HTTP 端点。对端点的任何请求都会导致传递给onRequest()
回调的 ExpressJS 样式的 Request 和 Response 对象。HTTP 函数是同步的(类似于 可调用函数),因此您应该尽快发送响应并使用 Cloud Firestore 推迟工作。
addMessage()
HTTP 函数将文本值传递给 HTTP 端点,并将其插入路径/messages/:documentId/original
下的数据库中。
// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
// Grab the text parameter.
const original = req.query.text;
// Push the new message into Firestore using the Firebase Admin SDK.
const writeResult = await admin.firestore().collection('messages').add({original: original});
// Send back a message that we've successfully written the message
res.json({result: `Message with ID: ${writeResult.id} added.`});
});
对于
makeUppercase()
函数,将这些行添加到index.js
:
makeUppercase()
函数在写入 Cloud Firestore 时执行。ref.set
函数定义要侦听的文档。出于性能原因,您应该尽可能具体。大括号——例如,
{documentId}
——围绕“参数”,通配符在回调中公开它们的匹配数据。每当添加新消息时,Cloud Firestore 都会触发
onCreate()
回调。
// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore.document('/messages/{documentId}')
.onCreate((snap, context) => {
// Grab the current value of what was written to Firestore.
const original = snap.data().original;
// Access the parameter `{documentId}` with `context.params`
functions.logger.log('Uppercasing', context.params.documentId, original);
const uppercase = original.toUpperCase();
// You must return a Promise when performing asynchronous tasks inside a Functions such as
// writing to Firestore.
// Setting an 'uppercase' field in Firestore document returns a Promise.
return snap.ref.set({uppercase}, {merge: true});
});
- 测试和部署函数
Firebase Local Emulator Suite 允许您在本地计算机上构建和测试应用程序,而不是部署到 Firebase 项目。
运行此命令以部署您的函数:
firebase deploy --only functions
运行此命令后,Firebase CLI 会输出任何 HTTP 函数端点的 URL。在您的终端中,您应该会看到如下一行:
Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
2.3 一些简单的 Cloud Functions 实例
可以访问下面这个 地址 来查看一些官方示例:
https://github.com/firebase/functions-samples
2.4 Cloud Functions 的一些局限性
- 当数据库较大时,Firestore 触发会存在 1 到 2 秒的延时,对于一些高时效性数据可以选择手动写入。
- Cloud Functions 对 Firestore 的读写也是计费的,因此需要优化函数的触发条件和内部执行方式,避免费用过高的问题。
3 小结
基于这两个系统,可以实现 Unity 的公会系统 公会系统。
4 参考文档
更多内容可以查阅 Firestore 和 Cloud Functions 的官方文档,以及一些 官方示例。
- Firestore: https://firebase.google.com/docs/firestore?authuser=0
- Cloud Functions: https://firebase.google.com/docs/functions?authuser=0
- functions-samples: https://github.com/firebase/functions-samples