Firebase App Check 錯誤排解:403、App attestation failed、無效權杖
App Check 錯誤出在兩個步驟之一:應用程式透過認證供應商(Play Integrity、App Attest、reCAPTCHA)取得權杖的步驟,或 Firebase 服務驗證該權杖的步驟。前一步失敗,後一步也會失敗,所以不要只看服務的錯誤,請先找出權杖交換的錯誤,再修正各平台的註冊值。Android 模擬器、iOS 模擬器和 localhost 本來就無法通過認證,所以要使用偵錯權杖。
重點整理
- 先找出失敗的步驟。權杖交換以 403 結束,是供應商的設定問題;沒有交換錯誤、只有服務拒絕要求,則是權杖缺少或無效。從訊息區分
- 開發環境使用偵錯權杖。Android 模擬器、iOS 模擬器、localhost 和偵錯簽署的版本,都無法通過實際的認證。註冊方法
- 每個平台都有必須相符的值。Android 是簽署憑證的 SHA-256,Apple 是 Team ID 和 App Attest 的 production 環境,Web 是 reCAPTCHA 金鑰的網域。各平台的原因
- AI Logic 自 2026 年 11 月 2 日起自動強制執行 App Check。最晚只能延到 2027 年 1 月 21 日。該怎麼做
從訊息找出失敗的步驟
| 訊息 | 失敗的步驟 |
|---|---|
Android:Error returned from API. code: 403 body: App attestation failed. | 取得權杖。App Check 伺服器沒有接受 Play Integrity 的結果。 |
Apple:The server responded with an error … HTTP status code: 403 | 取得權杖。App Attest 或 DeviceCheck 的結果沒有被接受。 |
Web:HTTP status: 403. (appCheck/fetch-status-error),接著是 appCheck/throttled | 取得權杖。reCAPTCHA 的結果沒有被接受,SDK 在 24 小時內不會重試。 |
Cloud Storage:Firebase App Check token is invalid.(Web SDK 中為 storage/unauthorized-app) | 使用權杖。權杖缺少或無效。 |
可呼叫函式(callable):functions/unauthenticated | 使用權杖。設定了 enforceAppCheck: true 的函式拒絕了要求。Auth 權杖有誤時傳回的也是這個代碼,要靠函式記錄中的 AppCheck token was rejected 來區分。 |
Realtime Database:Provided AppCheck credentials for the app named ... are invalid | 使用權杖。權杖無效。 |
Firebase AI Logic:403 PERMISSION_DENIED: ... you must enforce Firebase App Check. | 使用權杖。請參閱 AI Logic 一節。 |
沒有取得權杖時,服務要求中就沒有有效的權杖(Web SDK 會附上預留位置權杖送出)。所以即使看到的是服務傳回的錯誤,也請先確認是否同時記錄了取得權杖的錯誤。失敗之後,SDK 會延後重試。Web 在 403、404 之後為 24 小時,Android 和 Apple 在 400、404 之後為 24 小時,其他錯誤最多 4 小時。這個狀態只存在記憶體中,所以修正設定後,請重新啟動應用程式或重新整理網頁再確認。
開發時使用偵錯權杖
Android 模擬器和 iOS 模擬器都不算有效裝置,沒有在 Google Play 上架的偵錯版本也無法通過 Play Integrity。原則上不應將 localhost 加入 reCAPTCHA 金鑰。在這些環境中,請啟用偵錯供應商,並將記錄中輸出的權杖註冊到控制台。
- 只在開發版本中啟用偵錯供應商。
// Android (Kotlin): com.google.firebase:firebase-appcheck-debug Firebase.appCheck.installAppCheckProviderFactory( if (BuildConfig.DEBUG) DebugAppCheckProviderFactory.getInstance() else PlayIntegrityAppCheckProviderFactory.getInstance(), ) // iOS (Swift): before FirebaseApp.configure() #if DEBUG AppCheck.setAppCheckProviderFactory(AppCheckDebugProviderFactory()) #endif // Web: before initializeAppCheck(), in development builds only self.FIREBASE_APPCHECK_DEBUG_TOKEN = true; // Flutter (firebase_app_check 0.5+) await FirebaseAppCheck.instance.activate( providerAndroid: kDebugMode ? const AndroidDebugProvider() : const AndroidPlayIntegrityProvider(), providerApple: kDebugMode ? const AppleDebugProvider() : const AppleAppAttestWithDeviceCheckFallbackProvider(), ); - 執行應用程式,在記錄中找出 debug token。新版 SDK 會以
Firebase App Check debug token: <UUID>的格式輸出(Android 在 logcat,Apple 在 Xcode 主控台,Web 在瀏覽器主控台)。 - 註冊權杖。在 Firebase 控制台的 App Check 中開啟應用程式(Apps)分頁,從應用程式的 ⋮ 選單選取管理偵錯權杖(Manage debug tokens)。每個應用程式最多可註冊 20 個。
- 權杖會改變。Android 清除應用程式資料或重新安裝、Apple 重新安裝、Web 改用其他瀏覽器設定檔或清除網站資料後,都會產生新的權杖。新的權杖必須重新註冊。
- 在 CI 中傳入已註冊的權杖。Web 將權杖字串指定給
self.FIREBASE_APPCHECK_DEBUG_TOKEN,Android 使用檢測設備測試引數firebaseAppCheckDebugSecret,Apple 使用 scheme 環境變數AppCheckDebugToken,Flutter 使用debugToken參數。 - 像對待密碼一樣對待權杖。不要提交到存放區,也不要將偵錯供應商和權杖放進正式版本。
各平台的原因
Android(Play Integrity)
| 症狀 | 原因 | 解決方法 |
|---|---|---|
| 只在模擬器或偵錯版本上失敗 | 模擬器不是有效裝置,Google Play 也不認得偵錯簽署。 | 偵錯權杖 |
| 從 Play 安裝的應用程式失敗 | 註冊的是上傳金鑰的 SHA-256。使用 Play 應用程式簽署時,Google 會用應用程式簽署金鑰重新簽署。 | 在 Play Console 中點選前往 Play 應用程式簽署(Manage Play app signing),將該頁面上應用程式簽署金鑰憑證的 SHA-256 註冊到 App Check |
| 在 Play 以外發布的應用程式失敗 | 預設設定只放行 Google Play 認得的應用程式版本(PLAY_RECOGNIZED)。 | 在 App Check 的 Play Integrity 設定中,將 PLAY_RECOGNIZED 改為非必要(Not required),並將最低裝置完整性等級提高到裝置完整性(Device integrity) |
使用者變多後失敗(TOO_MANY_REQUESTS,-8) | 未連結 Play Console 的 Cloud 專案,Play Integrity 要求每天限 1 萬次。 | 在 Play Console 的 Play Integrity API 項目中,透過連結雲端專案(Link Cloud project)連結 Firebase 專案,需要時再申請提高配額。只有 Google Play 上的應用程式才能連結。 |
Apple(App Attest、DeviceCheck)
| 症狀 | 原因 | 解決方法 |
|---|---|---|
| 在模擬器上失敗 | 模擬器不是有效裝置。 | 偵錯權杖 |
| 只有從 Xcode 安裝的版本失敗 | 新增 App Attest capability 後,環境會設為 development,而 App Check 不接受這個環境的結果。TestFlight 和 App Store 的版本一律是 production。 | 將 entitlements 檔案中的 App Attest Environment 設為 production |
| 所有裝置上都失敗 | 在 Firebase 註冊的 Team ID 與應用程式的不一致。 | 在 Firebase 專案設定的 Apple 應用程式中輸入正確的 Team ID |
| 在 Mac 或 App 延伸功能中失敗 | 這些環境不支援 App Attest。 | 加入 DeviceCheck 做為備援供應商。DeviceCheck 需要將在 Apple 開發人員網站建立的私密金鑰(.p8)及其金鑰 ID 註冊到 App Check |
| Flutter:選擇的供應商在實體裝置上沒有被使用 | 如果先在 AppDelegate 中呼叫 FirebaseApp.configure(),providerApple 就會被忽略。 | 刪除 AppDelegate 中的 configure(),只使用 Dart 中的 Firebase.initializeApp() |
Web(reCAPTCHA)
| 症狀 | 原因 | 解決方法 |
|---|---|---|
| 只在已部署的網站上失敗 | 該網域不在 reCAPTCHA 金鑰的網域清單中。 | 在金鑰設定中新增網域。最多需要 30 分鐘才會生效 |
| 在 localhost 上失敗 | 正式環境用的金鑰不會加入 localhost。 | 偵錯權杖 |
| 更換金鑰後失敗 | 供應商類別與在 Firebase 註冊的值不相符。 | Enterprise 金鑰在程式碼中用 ReCaptchaEnterpriseProvider,在 Firebase 中填網站金鑰。v3 金鑰在程式碼中用 ReCaptchaV3Provider,在 Firebase 中填密鑰 |
| 修正後仍然失敗 | 403、404 之後,SDK 在 24 小時內不會重試權杖交換。 | 重新整理網頁。這個狀態只存在記憶體中。 |
AI Logic:自 2026 年 11 月 2 日起自動強制執行
自 2026 年 11 月 2 日起,Firebase 會為尚未強制執行 App Check 的專案,自動對 Firebase AI Logic 強制執行 App Check。沒有有效權杖的要求會遭到封鎖,未整合 App Check 就已發布的應用程式版本也一樣。提到 App Check 的 AI Logic 錯誤有兩種。
403 PERMISSION_DENIED: To access this model, you must enforce
Firebase App Check.
403 PERMISSION_DENIED: Firebase AI Logic has been deactivated in this
project. To resume using Firebase AI Logic, you must enforce Firebase
App Check.- 第一種是在沒有有效 App Check 權杖的情況下,呼叫了常遭濫用的模型。請設定並強制執行 App Check。開發時使用偵錯供應商。
- 第二種是專案被判定為閒置,而且沒有強制執行 App Check。如果已經在強制執行卻仍出現這個錯誤,請檢查重播保護(replay protection)。開啟時(包括 Monitor only 模式)只接受有限用途權杖(limited-use token)。
如果沒有 App Check 的版本仍在使用者手中,可以延後強制執行。在 App Check 的 API(APIs)分頁中修改 Firebase AI Logic 那一列的 Enforces 日期即可,最晚為 2027 年 1 月 21 日。如果已經處於已強制執行(Enforced)狀態,修改日期後,還要在該列的設定(Set up)中將基本保護(Baseline protection)改為 Unenforced (monitoring only),將重播保護改為 Disabled,才能解除。Google 不建議這麼做,請在那之前發布已整合 App Check 的版本。
對其他服務強制執行之前
- 先看指標。App Check 的 API(APIs)分頁會依服務將要求分為已驗證(Verified)、過時的用戶端(Outdated client,沒有權杖)、來源不明(Unknown origin)和無效(Invalid)。強制執行後只有已驗證的要求能通過,所以請在近期要求幾乎都已驗證時再強制執行。
- 舊版應用程式會遭到封鎖。沒有 App Check SDK 的版本,從強制執行的那一刻起,要求就會遭到拒絕。
- 最多需要 15 分鐘才會生效。不要一啟用強制執行就判斷結果。
- Cloud Functions 只能對可呼叫函式強制執行。加上
enforceAppCheck: true並重新部署後才會生效。onRequest函式不在 App Check 強制執行的範圍內,必須用 Admin SDK 自行驗證權杖。
資料來源
- App Check 總覽、啟用強制執行、監控指標、偵錯權杖數量上限(REST)
- Play Integrity 供應商、Play Integrity 配額、Android 偵錯供應商
- App Attest 供應商、DeviceCheck 供應商、Apple 偵錯供應商、App Attest 環境(Apple)、可使用 App Attest 的環境(Apple)
- reCAPTCHA Enterprise 供應商、reCAPTCHA v3 供應商、建立 reCAPTCHA 金鑰、Web 偵錯供應商
- Flutter 偵錯供應商、
firebase_app_check的activate() - AI Logic 的 App Check、AI Logic 錯誤代碼、Cloud Functions 的 App Check、在自建後端驗證權杖
- SDK 原始碼:Web 的重試限制、Web 的預留位置權杖、Storage 的拒絕方式、Android 錯誤訊息、Android 重試、Apple 重試、可呼叫函式的拒絕方式
