You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang实现Firebase Storage上传并获取与Rescript同格式下载URL

如何在Golang中生成与Firebase SDK格式一致的无过期下载URL

核心原因

你用Golang生成的是Google Cloud Storage(GCS)签名URL,而Rescript中Firebase SDK返回的是Firebase Storage下载令牌URL,二者属于不同的访问机制:

  • GCS签名URL基于服务账号签名逻辑,即使设置100年有效期,本质仍是带签名的临时访问链接
  • Firebase下载令牌是Firebase层面的永久访问凭证(除非手动撤销),格式固定为https://firebasestorage.googleapis.com/v0/b/{bucket}/o/{object-path}?alt=media&token={token}

解决方案

要生成格式一致的URL,需给上传的Firebase Storage对象设置firebaseStorageDownloadTokens元数据,再按固定格式拼接URL:

  1. 生成一个UUID作为下载令牌
  2. 上传文件后,更新对象元数据,添加该令牌
  3. 按照Firebase标准格式拼接下载URL

修改后的Golang代码示例

import (
    "context"
    "fmt"
    "io"
    "log"
    "os"
    "github.com/google/uuid"
    "firebase.google.com/go"
    "firebase.google.com/go/storage"
    "google.golang.org/api/option"
)

func main() {
    myBucketName := "your-bucket-name"
    myServiceAccountKeyFileName := "service-account.json"
    myFilePath := "path/to/local/file"
    objectPath := "target/folder/filename" // 对应Rescript中的`${id}/${filename}`

    config := &firebase.Config{
        StorageBucket: myBucketName,
    }
    app, err := firebase.NewApp(context.Background(), config, option.WithCredentialsFile(myServiceAccountKeyFileName))
    if err != nil {
        log.Fatalf("初始化App失败: %v\n", err)
    }

    client, err := app.Storage(context.Background())
    if err != nil {
        log.Fatalf("初始化Storage客户端失败: %v\n", err)
    }

    file, err := os.Open(myFilePath)
    if err != nil {
        log.Fatalf("打开本地文件失败: %v\n", err)
    }
    defer file.Close()

    ctx := context.Background()
    bucket, err := client.DefaultBucket()
    if err != nil {
        log.Fatalf("获取默认Bucket失败: %v\n", err)
    }

    // 上传文件到指定路径
    object := bucket.Object(objectPath)
    writer := object.NewWriter(ctx)
    if _, err := io.Copy(writer, file); err != nil {
        log.Fatalf("上传文件失败: %v\n", err)
    }
    if err := writer.Close(); err != nil {
        log.Fatalf("关闭写入器失败: %v\n", err)
    }
    fmt.Println("文件上传成功")

    // 生成下载令牌(UUID格式)
    downloadToken := uuid.NewString()

    // 更新对象元数据,添加Firebase专属下载令牌字段
    _, err = object.Update(ctx, storage.ObjectAttrsToUpdate{
        Metadata: map[string]string{
            "firebaseStorageDownloadTokens": downloadToken,
        },
    })
    if err != nil {
        log.Fatalf("更新对象元数据失败: %v\n", err)
    }

    // 拼接Firebase标准格式下载URL(需编码路径特殊字符)
    encodedObjectPath := storage.URL.EncodePath(objectPath)
    downloadURL := fmt.Sprintf("https://firebasestorage.googleapis.com/v0/b/%s/o/%s?alt=media&token=%s",
        myBucketName, encodedObjectPath, downloadToken)

    fmt.Println("Firebase格式下载URL:", downloadURL)
}

关键说明

  • firebaseStorageDownloadTokens是Firebase Storage识别的固定元数据字段,设置后会被作为永久访问令牌使用
  • 必须对对象路径进行URL编码(通过storage.URL.EncodePath),避免路径中的特殊字符导致URL失效
  • 该令牌无过期时间,除非手动删除或更新对象的元数据字段

内容的提问来源于stack exchange,提问作者IFeel3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 00:32:34