Firebase Admin SDK 将文件上传到 Google 云存储

Firebase Admin SDK Upload File to Google Cloud Storage

过去几天这一直是令人沮丧的根源,因为文档让它听起来应该很简单。

我有一个简单的 HTTP 服务器运行在本地(最终是 Heroku),我想用作将文件上传到 Firebase 云存储的直通。我有一个凭据文件并且能够成功初始化 Firebase 应用程序并验证 JWT,但是当我尝试放置一个对象时,我总是会收到错误消息。

这是代码 --

func main() {
   config := &firebase.Config{
      ProjectID:     "myproject-id",
      StorageBucket: "myproject-id.appspot.com",
   }
   credentialsJSON := os.Getenv("GOOGLE_CREDENTIALS")
   creds := google.Credentials{JSON: []byte(credentialsJSON)}
   opt := option.WithCredentials(&creds)

   app, err := firebase.NewApp(context.Background(), config,
    opt)

   if err != nil {
     log.Fatalln(err)
   }
   ctx, cancel := context.WithTimeout(context.Background(), time.Second*50)
   defer cancel()

   client, err := app.Storage(ctx)
   if err != nil {
     log.Fatalln(err)
   }
   fmt.Println(client)

   bucket, err := client.DefaultBucket()

   object := bucket.Object("foo.png")
   wc := object.NewWriter(ctx)

   r, err := os.Open("/Users/foo/test.png")
   defer r.Close()

   if _, err = io.Copy(wc, r); err != nil {
      log.Error(err)
   }

   if err := wc.Close(); err != nil {
     fmt.Println(err)
     log.Error(err)
   }
}

但这就是我在 运行 这段代码时得到的 --

 Post "https://storage.googleapis.com/upload/storage/v1/b/myproject-id.appspot.com/o?alt=json&name=foo.png&prettyPrint=false&projection=full&uploadType=multipart": oauth2: Transport's Source is nil

Firebase Admin SDK 文档明确指出服务帐户对存储帐户具有完全控制范围,但由于传输令牌源为零,因此正确引导凭据似乎存在一些错误。

如果您要直接初始化 google.Credentials 结构,则必须指定其 TokenSource 字段。仅指定 JSON 是不够的。查看google.golang.org/api/transport包是如何实现的:

https://github.com/googleapis/google-api-go-client/blob/144dbf001968463675e3221ab95bce7a93039a28/transport/http/dial.go#L81-L98

注意它只关心 creds.TokenSource.

将凭据传递给 Admin SDK 的更常见方法是通过 option.WithCredentialsJSON(p []byte)