我有一个用 Go 编写的基本函数并部署到 GCP(不是 Firebase 云函数,而是 GCP 云函数)。我需要此函数来访问 Firestore 中的单个集合,以检索令牌以通过 FCM 发送通知。
在 IAM 和 ADMIN > IAM 下,我有一个具有以下权限的服务帐户:Cloud Datastore User、Cloud Functions Invoker、Cloud Functions Service Agent、Editor、Firebase Admin SDK Administrator Service Agent、Firebase Cloud Messaging Admin、Service Account Token Creator、服务帐户用户、查看者
在我的函数 > 权限下,我将此服务帐户列为具有以下权限的主体:Cloud Functions Admin、Cloud Functions Invoker、Cloud Functions Service Agent、Editor、Firebase Admin
我已经在函数详细信息中验证了正确的服务帐户已附加到此函数,但我仍然收到此错误:
{"error":"rpc error: code = PermissionDenied desc = Missing or insufficient permissions."}
该函数创建 Firestore 客户端没有问题,但无法读取任何文档:
// setting the client
func _setFirestoreClient(ctx context.Context) (firestore.Client, error) {
if client, err := firestore.NewClient(ctx, _projectId); err != nil {
return firestore.Client{}, err
} else {
return *client, err
}
}
// using the client
data, err := firestoreClient.Collection("tokens").Doc(requestBody.ReceiverUserUid).Get(ctx)
是否有关于如何从 GCP 读取 Firestore 文档的可靠文档来源?我不完全确定如何继续,因为我 99% 确定我拥有正确的权限 - 老实说,我可能还包含不必要的权限 - 并且我的 Firestore 安全规则允许从经过身份验证的用户读取,因此 Firebase Admin SDK 应该能够毫无问题地阅读此内容。
请指教。
编辑
很抱歉没有包含足够的信息。这是函数文件:
package sendnotification
import (
"context"
"encoding/json"
"fmt"
"net/http"
"time"
"cloud.google.com/go/firestore"
firebase "firebase.google.com/go"
"firebase.google.com/go/messaging"
)
func SendNotification(w http.ResponseWriter, req *http.Request) {
requestBody, err := _parseRequest(w, req)
if err != nil {
// handle error and return
}
ctx := context.Background()
var firestoreClient firestore.Client
if client, err := _setFirestoreClient(ctx); err != nil {
// handle error and reurn
} else {
firestoreClient = client
defer firestoreClient.Close()
}
var tokenData TokenDocument
data, err := firestoreClient.Collection("tokens").Doc(requestBody.ReceiverUserUid).Get(ctx)
// function continues to send data through FCM
}
这一切都在我使用凭据配置 gcloud 的本地工作,因此当我启动本地服务器并点击此功能的端点时,我可以毫无问题地读取 Firestore
事实证明,大约 3 个月前,我创建了第二个项目来包含我正在创建的所有云函数 API。该项目不属于 Firebase 项目,因此无法访问 Firestore。我在 GCP CLI 中切换了项目 ID,如下所示:
gcloud config set project <project-id>
然后,我将函数重新部署到云中,并且能够访问 Firestore,而无需为服务帐户设置其他 IAM 角色。 Firebase 项目的默认服务帐户已有权从 Firestore 读取数据。