Summary
Production iOS App Check assertions on Firebase Authentication API are landing in the "Unverified: invalid" bucket at ~100% across our entire TestFlight fleet (physical iOS 26.x devices). The metric collapsed to ~0% verified after May 1, 2026 and has stayed there. Critically, 0% of requests fall into the "Outdated client" bucket across the entire 7-day window β meaning the SDK is attaching App Check tokens reliably; what's failing is downstream cryptographic validation of those tokens.
Current metrics (Firebase Console β App Check β Authentication API β Last 7 days, Apr 27 β May 5, 2026)
| Bucket |
7-day total |
May 2β3 |
May 3β4 |
| Verified |
11% (46/409) |
7% |
0% |
| Unverified β outdated client |
0% (0/409) |
0% |
0% |
| Unverified β unknown origin |
7% (28/409) |
0% |
0% |
| Unverified β invalid |
82% (335/409) |
93% |
100% |
The 7% "unknown origin" total is concentrated entirely on Apr 28 and was caused by an initializeAppCheck race condition (resolved Apr 29 by await-ing the init promise inside
onAuthStateChanged before any getIdToken call). It self-resolved as soon as the fix shipped β not the symptom we're filing about.
The 82% "invalid" signal is the issue. Tokens are reaching Firebase and being rejected as cryptographically invalid.
Versions
| Package |
Version |
@react-native-firebase/app |
^24.0.0 |
@react-native-firebase/auth |
^24.0.0 |
@react-native-firebase/app-check |
^24.0.0 |
| Expo SDK |
~54.0.33 |
| React Native |
0.81.5 |
| iOS (test devices) |
26.3.1 + others on 26.x |
Configuration
app.json (relevant excerpt):
"ios": {
"bundleIdentifier": "com.example.app",
"entitlements": {
"com.apple.developer.devicecheck.appattest-environment": "production",
"aps-environment": "production"
}
},
"plugins": [
"@react-native-firebase/app",
"@react-native-firebase/app-check",
["expo-build-properties", {
"ios": {
"useFrameworks": "static",
"forceStaticLinking": ["RNFBApp", "RNFBAuth", "RNFBAppCheck"]
}
}]
]
App Check init (runs at module load, before any Firebase Auth call):
const APP_CHECK_DEBUG_TOKEN = "<REDACTED-registered-in-firebase-console>";
const appCheckProvider = new ReactNativeFirebaseAppCheckProvider();
appCheckProvider.configure({
apple: {
provider: __DEV__ ? "debug" : "appAttestWithDebugProviderFallback",
debugToken: APP_CHECK_DEBUG_TOKEN,
},
android: {
provider: __DEV__ ? "debug" : "playIntegrity",
debugToken: APP_CHECK_DEBUG_TOKEN,
},
});
const appCheckReady = initializeAppCheck(getApp(), {
provider: appCheckProvider,
isTokenAutoRefreshEnabled: false,
}).catch((err) => console.error("App Check init failed:", err));
// Auth listener awaits App Check before any network call
onAuthStateChanged(getAuth(), async (user) => {
await appCheckReady;
// ... getIdToken + backend sync
});
Ruled out (extensive)
- β
Token attachment / SDK race β 0% "outdated client" across entire window. Tokens are being attached.
- β
initializeAppCheck race condition β appCheckReady promise awaited before any getIdToken call. Apr 28 unknown-origin spike confirmed this fix worked; it's been at 0% since.
- β
Provisioning profile drift β same UUID 7ecd79b2-β¦ and same code-signing identity hash across the verified-traffic build and the failing build (verified via Xcode build logs from EAS).
- β
App ID capabilities β App Attest capability still active on the App ID; entitlements (com.apple.developer.devicecheck.appattest-environment = production) successfully signed into both
IPAs, which Apple wouldn't permit if the capability had been revoked.
- β
Firebase Console iOS app config β Bundle ID, Team ID, App Attest provider all registered. GoogleService-Info.plist byte-identical between local working tree, 1Password vault, and
Firebase Console download (all four primary fields verified: BUNDLE_ID, GOOGLE_APP_ID, PROJECT_ID, GCM_SENDER_ID).
- β
Pod / package-lock drift β package.json and package-lock.json byte-identical between the verified-traffic build and the failing build.
- β
forceStaticLinking β array contains RNFBApp, RNFBAuth, RNFBAppCheck (all three present); useFrameworks: static.
- β
isTokenAutoRefreshEnabled amplification hypothesis β flipped from true to false on May 4 in case auto-refresh was over-attesting. No measurable improvement in metric (still 100%
invalid on May 3β4).
- β
Apple System Status / Firebase Status β green throughout the window.
- β
DeviceCheck not engaged β provider is appAttestWithDebugProviderFallback (or pure appAttest after our planned hygiene patch); DeviceCheck section in Firebase Console is intentionally
unconfigured.
Questions for the maintainers
1. What conditions specifically produce "Unverified: invalid"? Our reading is that this categorization specifically means a token was sent and Firebase rejected its signature as
cryptographically invalid (vs. "Outdated client" = no token / unrecognized SDK version, vs. "Unknown origin" = unrecognized app context). Can you confirm?
2. Has anyone reported a similar fleet-wide invalid-rate regression on iOS 26.x with @react-native-firebase/app-check@24.0.0? Looking specifically for a server-side or vendor-side change
between late April and early May 2026 that could affect App Attest assertion validation.
3. appAttestWithDebugProviderFallback semantics β our reading is that the fallback only engages when App Attest is unavailable on the device (simulator, jailbreak, ancient iOS). It does NOT
engage when App Attest produces an assertion that Firebase rejects as invalid. Can you confirm? We're shipping a hygiene build with pure appAttest to remove the fallback as a confounding
variable, but want to verify the semantics first.
4. Is there a way to capture the rejected assertion server-side (via Firebase support) or client-side (via debug logging) without disabling App Check enforcement? We'd like to inspect the
assertion payload that's being marked invalid.
5. Could DeviceCheck silently engage under any RNFB or iOS Firebase SDK condition, given a provider: "appAttest" configuration and an unconfigured DeviceCheck section in Firebase Console?
Strict read of the API contract says no, but we want to rule it out β DeviceCheck unconfigured + accidentally-engaged would produce exactly this "invalid" signature without affecting any
other observable behavior.
Reproduction
Currently 100% reproducible across our device tester fleet. Manifested ~7 days after first install on each device β consistent with App Attest token TTL expiry forcing fresh attestations that then fail validation. Happy to ship a debug build to a maintainer's test device, or to share raw Xcode build logs / unredacted Firebase Console exports privately.
Summary
Production iOS App Check assertions on Firebase Authentication API are landing in the "Unverified: invalid" bucket at ~100% across our entire TestFlight fleet (physical iOS 26.x devices). The metric collapsed to ~0% verified after May 1, 2026 and has stayed there. Critically, 0% of requests fall into the "Outdated client" bucket across the entire 7-day window β meaning the SDK is attaching App Check tokens reliably; what's failing is downstream cryptographic validation of those tokens.
Current metrics (Firebase Console β App Check β Authentication API β Last 7 days, Apr 27 β May 5, 2026)
The 7% "unknown origin" total is concentrated entirely on Apr 28 and was caused by an
initializeAppCheckrace condition (resolved Apr 29 byawait-ing the init promise insideonAuthStateChangedbefore anygetIdTokencall). It self-resolved as soon as the fix shipped β not the symptom we're filing about.The 82% "invalid" signal is the issue. Tokens are reaching Firebase and being rejected as cryptographically invalid.
Versions
@react-native-firebase/app@react-native-firebase/auth@react-native-firebase/app-checkConfiguration
app.json(relevant excerpt):