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

Golang中Firebase Auth初始化失败问题求助

Firebase Auth初始化失败问题排查与解决

问题背景

我是Go语言新手,参考代码实现Firebase JWT令牌校验功能,运行程序时出现错误:

failed to init firebase auth 2 error initializing firebase auth (creating client): google: could not find default credentials. See https://cloud.google.com/docs/authentication/external/set-up-adc for more information

已编写的代码与配置如下:

main.go

package main

import (
    "log"

    "github.com/gin-gonic/gin"
    "package.com/components"
    "package.com/config"
)

type Response struct {
    Message string `json:"message"`
}

func main() {
    client, err := config.InitAuth()
    if err != nil {
        log.Fatalln("failed to init firebase auth 2", err)
    }

    r := gin.Default()

    versioned := r.Group("/v1")
    versioned.Use(config.AuthJWT(client))

    versioned.POST("/", func(c *gin.Context) {
        log.Println("created task")
    })

    versioned.GET("/test", components.GetWorkouts)

    errRun := r.Run()
    if errRun != nil {
        log.Fatalln("failed to run Gin app")
    }
}

fbauth.go

package config

import (
    "context"
    "os"

    firebase "firebase.google.com/go"
    "firebase.google.com/go/auth"
    "github.com/pkg/errors"
    "google.golang.org/api/option"
)

var (
    firebaseConfigFile = os.Getenv("FIREBASE_CONFIG_FILE")
)

func InitAuth() (*auth.Client, error) {
    opt := option.WithCredentialsFile(firebaseConfigFile)
    app, err := firebase.NewApp(context.Background(), nil, opt)
    if err != nil {
        return nil, errors.Wrap(err, "error initializing firebase auth (create firebase app)")
    }

    client, errAuth := app.Auth(context.Background())
    if errAuth != nil {
        return nil, errors.Wrap(errAuth, "error initializing firebase auth (creating client)")
    }

    return client, nil
}

middleware.go

package config

import (
    "log"
    "net/http"
    "strings"
    "time"

    "firebase.google.com/go/auth"
    "github.com/gin-gonic/gin"

    "package.com/config/secrets"
)

const (
    authorizationHeader = "Authorization"
    apiKeyHeader        = "X-API-Key"
    cronExecutedHeader  = "X-Appengine-Cron"
    valName             = "FIREBASE_ID_TOKEN"
)

func AuthJWT(client *auth.Client) gin.HandlerFunc {
    return func(c *gin.Context) {
        startTime := time.Now()

        authHeader := c.Request.Header.Get(authorizationHeader)
        log.Println("authHeader", authHeader)
        token := strings.Replace(authHeader, "Bearer ", "", 1)
        idToken, err := client.VerifyIDToken(c, token)
        if err != nil {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
                "code":    http.StatusUnauthorized,
                "message": http.StatusText(http.StatusUnauthorized),
            })
            return
        }

        log.Println("Auth time:", time.Since(startTime))
        c.Set(valName, idToken)
        c.Next()
    }
}

func AuthAPIKey(secretId string) gin.HandlerFunc {
    return func(c *gin.Context) {
        key := c.Request.Header.Get(apiKeyHeader)

        secret, err := secrets.GetSecret(secretId)
        if err != nil {
            log.Println("failed to get secret")
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
                "code":    http.StatusUnauthorized,
                "message": http.StatusText(http.StatusUnauthorized),
            })
            return
        }

        if secret != key {
            log.Println("key doesnt match!")
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
                "code":    http.StatusUnauthorized,
                "message": http.StatusText(http.StatusUnauthorized),
            })
            return
        }
        c.Next()
    }
}

func AuthAppEngineCron() gin.HandlerFunc {
    return func(c *gin.Context) {
        cron := c.Request.Header.Get(cronExecutedHeader)

        if cron != "true" {
            log.Println("not invoked by cron - access denied")
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
                "code":    http.StatusUnauthorized,
                "message": http.StatusText(http.StatusUnauthorized),
            })
            return
        }
        c.Next()
    }
}

.env配置

FIREBASE_CONFIG_FILE="./firebase.json"
API_KEY_NAME="AIzaXXXXXXXXXX"

firebase.json配置

{
  "type": "service_account",
  "project_id": "mobile-test",
  "private_key_id": "4870XXXXXXXXX",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEGYE=\n-----END PRIVATE KEY-----\n",
  "client_email": "firebase-adminsdk-yqf07@mobile.iam.gserviceaccount.com",
  "client_id": "11590XXXXXX",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-yqf07%40wodhero-mobile.iam.gserviceaccount.com",
  "universe_domain": "googleapis.com"
}

解决方案

这个错误核心是程序未正确读取到Firebase服务账号密钥文件,或文件路径无效,按以下步骤排查:

1. 确保环境变量正确加载

Go不会自动加载.env文件,需手动引入包处理:

  • 安装依赖:go get github.com/joho/godotenv
  • 在main.go的main函数开头添加加载代码:
func main() {
    // 新增加载.env文件逻辑
    err := godotenv.Load()
    if err != nil {
        log.Println("warning: 加载.env文件失败")
    }

    client, err := config.InitAuth()
    // 后续代码不变
}

2. 验证文件路径有效性

  • 确认firebase.json和.env在同一目录,程序运行的工作目录是项目根目录
  • 可临时改用绝对路径测试,比如把.env里的路径改成/home/yourname/projects/yourapp/firebase.json(替换为实际路径)

3. 检查文件权限

确保运行程序的用户有读取firebase.json的权限,Linux/macOS执行:

chmod 644 firebase.json

4. 确认服务账号密钥有效

  • 检查firebase.json中private_key格式正确,-----END PRIVATE KEY-----不能缺失
  • 核对project_id、client_email与Firebase控制台信息一致

5. 备选方案:直接通过环境变量传递密钥

若路径问题难排查,可将服务账号JSON内容设为环境变量GOOGLE_APPLICATION_CREDENTIALS,或在代码中直接加载JSON内容(不推荐硬编码密钥):

jsonContent := os.Getenv("FIREBASE_SERVICE_ACCOUNT_JSON")
opt := option.WithCredentialsJSON([]byte(jsonContent))
app, err := firebase.NewApp(context.Background(), nil, opt)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:06:05