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

Azure Pipeline中Firebase服务账号认证失败问题求助

Azure Pipeline中Firebase App Distribution服务账号认证失败排查

我正在Azure Pipeline中配置Firebase App Distribution,使用服务账号身份验证,但一直提示认证失败,要求执行firebase login。已经提供了服务账号密钥,正确设置了GOOGLE_APPLICATION_CREDENTIALS环境变量,也确认了服务账号拥有Firebase App Distribution的足够权限,但执行npx firebase projects:list测试认证仍然失败。

错误信息

/bin/bash --noprofile --norc /Users/runner/work/_temp/9862a4f1-6542-4b7b-9dbb-9782561da5bb.sh
Attempting Firebase authentication with service account...
##[debug]Agent environment resources - Disk: / Available 124774.09 MB out of 332471.96 MB, Memory: Used 7722.00 MB out of 14332.00 MB, CPU: Usage 99.30%
Error: Failed to authenticate, have you run firebase login?
Firebase authentication failed.
##[debug]Exit code 1 received from tool '/bin/bash'
##[debug]STDIO streams have closed for tool '/bin/bash'
##[error]Bash exited with code '1'.

Pipeline YAML配置

trigger: none

pool:
  vmImage: 'macOS-latest'

parameters:
  - name: appVariant
    displayName: 'App Variant'
    type: string
    default: '{{appName}}'
    values:
      - '{{appName}}'
      - 'BCDC'

  - name: firebaseEnv
    displayName: 'Firebase Environment'
    type: string
    default: 'UAT'
    values:
      - 'UAT'
      - 'Pilot'

  - name: testGroup
    displayName: 'Test Group'
    type: string
    default: 'Android_UAT_Testers'
    values:
      - 'Android_UAT_Testers'
      - 'Android_Pilot_Testers'

  - name: releaseNotes
    displayName: 'Release Notes'
    type: string
    default: 'No release notes provided.'

stages:
  - stage: Build
    jobs:
      - job: BuildJob
        timeoutInMinutes: 120
        variables:
          GRADLE_USER_HOME: $(Pipeline.Workspace)/.gradle

        steps:
          - task: CmdLine@2
            inputs:
              script: "sudo rm -rf $ANDROID_HOME/ndk/ && sudo rm -rf $ANDROID_HOME/ndk-bundle/"

          - ${{ if eq(parameters.appVariant, '{{appName}}') }}:
              - ${{ if eq(parameters.firebaseEnv, 'UAT') }}:
                  - task: Gradle@2
                    displayName: 'Gradle Compile {{appName}} for UAT'
                    inputs:
                      gradleWrapperFile: 'gradlew'
                      tasks: 'assembleUatOne{{appName}}GoogleDebug'

              - ${{ if eq(parameters.firebaseEnv, 'Pilot') }}:
                  - task: Gradle@2
                    displayName: 'Gradle Compile {{appName}} for Pilot'
                    inputs:
                      gradleWrapperFile: 'gradlew'
                      tasks: 'assemblePilotOne{{appName}}GoogleDebug'

          - ${{ if eq(parameters.appVariant, 'BCDC') }}:
              - ${{ if eq(parameters.firebaseEnv, 'UAT') }}:
                  - task: Gradle@2
                    displayName: 'Gradle Compile BCDC for UAT'
                    inputs:
                      gradleWrapperFile: 'gradlew'
                      tasks: 'assembleUatOne{{appName}}BcdcGoogleDebug'
              - ${{ if eq(parameters.firebaseEnv, 'Pilot') }}:
                  - task: Gradle@2
                    displayName: 'Gradle Compile BCDC for Pilot'
                    inputs:
                      gradleWrapperFile: 'gradlew'
                      tasks: 'assemblePilotOne{{appName}}BcdcGoogleDebug'

          - task: CopyFiles@2
            inputs:
              SourceFolder: $(Build.SourcesDirectory)
              contents: '**/*.apk'
              targetFolder: '$(build.artifactStagingDirectory)'
              overWrite: true

          - task: PublishBuildArtifacts@1
            inputs:
              pathtoPublish: '$(Build.ArtifactStagingDirectory)/app/build/outputs/apk/'
              artifactName: 'apks'
              publishLocation: 'container'

          - task: CmdLine@2
            displayName: 'Check Service Account and Credentials'
            inputs:
              script: |
                echo "$(MOBILEFIREBASEACCOUNTSERVICE)" > $(Pipeline.Workspace)/service-account.json
                export GOOGLE_APPLICATION_CREDENTIALS=$(Pipeline.Workspace)/service-account.json

                echo "GOOGLE_APPLICATION_CREDENTIALS is set to: $GOOGLE_APPLICATION_CREDENTIALS"
                echo "Service account JSON file:"
                cat $(Pipeline.Workspace)/service-account.json | jq '.'

                if [ -f "$(Pipeline.Workspace)/service-account.json" ]; then
                  echo "Service account file exists."
                else
                  echo "Service account file does NOT exist."
                  exit 1
                fi

          - task: CmdLine@2
            displayName: 'Install Firebase CLI'
            inputs:
              script: 'npm install -g firebase-tools'

          - task: CmdLine@2
            displayName: 'Authenticate Firebase CLI with Service Account'
            inputs:
              script: |
                echo "Attempting Firebase authentication with service account..."
                if npx firebase projects:list; then
                    echo "Firebase authentication successful."
                else
                    echo "Firebase authentication failed."
                    exit 1
                fi

          - task: CmdLine@2
            displayName: 'Distribute APK to Firebase (UAT)'
            condition: eq('${{ parameters.firebaseEnv }}', 'UAT')
            inputs:
              script: |
                npx firebase appdistribution:distribute "$(build.artifactStagingDirectory)/app/build/outputs/apk/uatOne{{appName}}Google/debug/app-uat-one{{appName}}-google-debug.apk" \
                  --app $(FIREBASE_APP_ID) \
                  --groups ${{ parameters.testGroup }} \
                  --release-notes "${{ parameters.releaseNotes }}" \
                  --debug

          - task: CmdLine@2
            displayName: 'Distribute APK to Firebase (Pilot)'
            condition: eq('${{ parameters.firebaseEnv }}', 'Pilot')
            inputs:
              script: |
                npx firebase appdistribution:distribute "$(build.artifactStagingDirectory)/app/build/outputs/apk/uatOne{{appName}}Google/release/app-uat-one{{appName}}-google-release.apk" \
                  --app $(FIREBASE_APP_ID) \
                  --groups ${{ parameters.testGroup }} \
                  --release-notes "${{ parameters.releaseNotes }}" \
                  --debug

排查与解决方案

1. 环境变量作用域问题

Check Service Account and Credentials任务中设置的GOOGLE_APPLICATION_CREDENTIALS仅对当前任务的Shell会话有效,后续任务无法继承该变量。

解决方法:
在每个需要认证的任务中重新导出环境变量,比如修改认证任务:

echo "Attempting Firebase authentication with service account..."
echo "$(MOBILEFIREBASEACCOUNTSERVICE)" > $(Pipeline.Workspace)/service-account.json
export GOOGLE_APPLICATION_CREDENTIALS=$(Pipeline.Workspace)/service-account.json
if npx firebase projects:list; then
    echo "Firebase authentication successful."
else
    echo "Firebase authentication failed."
    exit 1
fi

2. Firebase CLI版本不一致问题

使用npx firebase会每次拉取最新版本CLI,和全局安装版本可能存在差异,导致认证逻辑异常。

解决方法:
统一使用全局安装的firebase命令:

# 安装后直接使用firebase命令
if firebase projects:list; then
    echo "Firebase authentication successful."
else
    echo "Firebase authentication failed."
    exit 1
fi

3. 服务账号JSON格式校验

确保MOBILEFIREBASEACCOUNTSERVICE变量中的JSON未被转义或截断,可在检查任务中添加格式校验:

# 校验JSON格式是否合法
if ! jq . $(Pipeline.Workspace)/service-account.json > /dev/null 2>&1; then
    echo "Service account JSON is invalid."
    exit 1
fi

4. 服务账号权限复核

确认服务账号拥有以下权限:

  • Firebase App Distribution Admin角色(roles/firebase.appDistributionAdmin)
  • Firebase Viewer角色(roles/firebase.viewer)或更高权限
  • 已被添加到对应Firebase项目中

5. 网络连接测试

macOS虚拟机可能存在网络限制,可添加网络测试任务:

curl -v https://firebase.googleapis.com/

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 07:05:56