我们发现,在我们的用例中,Firestore REST API 比使用
firebase-admin
的默认数据库连接读取数据的性能要高得多。
我们在服务器上使用 Firestore,并且我们使用
read/write: false
规则在锁定状态下存储了一些敏感数据。这样,只有服务器可以从我们的服务帐户读取这些数据。
由于 Firestore 握手过程的性能原因,我们(因为我们使用 lambda)使用 REST API 从数据库请求数据要快得多。
但是,我们在访问锁定的数据时遇到了问题,因为授权 REST API 的唯一方法似乎是使用客户端的授权令牌。
我们需要一种通过 REST API 进行管理数据库访问的方法,是否有一些特殊的授权标头或 API 密钥我们无法在某个地方找到允许这样做?
您需要使用有权访问数据库的服务帐户的凭据进行身份验证。根据文档:
如果您使用服务帐户和 Google 验证您的请求 Identity OAuth 2.0 令牌,Cloud Firestore 假定您的请求 代表您的应用程序而不是个人用户进行操作。云 Firestore 允许这些请求忽略您的安全规则。 相反,Cloud Firestore 使用 Cloud Identity and Access Management (IAM) 以确定请求是否获得授权。
您项目的默认 App Engine 服务帐户应该已经能够执行此操作。一旦您拥有服务帐户的令牌,您就可以将其传递到请求的
Authorization
标头中,文档中也提到了这一点。
这里有一个node.js的例子供参考。
import { GoogleAuth } from 'google-auth-library';
async function getCollectionAsync(collection) {
try {
// needs GOOGLE_APPLICATION_CREDENTIALS or equivalent to be set
const googleAuth = new GoogleAuth({
scopes: ['https://www.googleapis.com/auth/cloud-platform']
});
const googleAuthClient = await googleAuth.getClient();
const tokenObj = await googleAuthClient.getAccessToken();
const token = tokenObj.token;
const projectId = googleAuthClient.projectId;
const parent = `projects/${projectId}/databases/(default)/documents`;
const url = `https://firestore.googleapis.com/v1/${parent}:runQuery`;
const Authorization = `Bearer ${token}`;
const headers = { Authorization, "Content-Type": "application/json" };
const body = {
structuredQuery: {
from: [{ collectionId: collection }],
limit: 40000, // OPTIONALLY: limit the number of documents
// OPTIONALLY: limit which fields are returned for speed
select: { fields: [{ "fieldPath": "__name__" }] }
}
};
const response = await fetch(url,
{ method: "POST", headers, body: JSON.stringify(body) });
const json = await response.json();
} catch (error) {
console.error(`Error getting collection ${collection}`, String(error));
return {};
}
}