◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/Dev Tools
⬡ Dev Tools/2026-05-19Advanced

Rolling Out Firebase App Check in Rork Without Breaking AdMob or Crashlytics

A practical, staged rollout for Firebase App Check in Rork apps that keeps Crashlytics reporting, Realtime Database listeners, and AdMob payouts intact — written from running AdMob-funded indie apps in production.

Firebase10App CheckAdMob73Crashlytics12Rork584Production10

✦ Premium Article

One Monday morning, my Crashlytics dashboard went almost completely quiet. For a few seconds I was happy — crash-free sessions had jumped to 99.97%. Then it sank in. Crashes were not down. Reports were not arriving. The night before, I had flipped Firebase App Check from "unenforced" to "enforced" on both Realtime Database and Crashlytics, and a chunk of my legitimate traffic was being rejected silently.

App Check is well documented and the official setup guides are clear enough. What they tend not to dwell on is how easy it is to take a production app down by toggling a single switch from a console UI. As an indie developer whose apps are funded by ads, App Check is still the one piece of Firebase infrastructure that makes me nervous every time I roll it out. So this is the design I now use for Rork apps, written from the side of someone who has already taken the blast.

Why "instant enforce" is a bad default in production

App Check verifies that a request to a Firebase backend came from a legitimate build of your app. iOS uses DeviceCheck or App Attest, Android uses Play Integrity, and your server-side enforcement decides whether unverified requests should be rejected with a 401. The conceptual model is clean: enforce attestation, drop spoofed traffic, sleep well.

The problem is that "unverified" is a much broader bucket than "spoofed." In practice, it also catches:

  1. App Attest assertions in the first few seconds of a freshly installed device, before the attestation key has been provisioned.
  2. Debug or TestFlight builds where the Debug Provider was never wired up.
  3. Internal QA sessions running on iOS Simulator or Android Emulator.

When App Check enforcement is on, every one of those is rejected. Crashlytics simply stops receiving reports. Realtime Database listeners fail to attach. Remote Config falls back to defaults forever. None of this is visible in your app logs — only in the Firebase console, on a screen you are not looking at unless you already know to.

So the rule I run by is: do not enable App Check enforcement in production without (a) a staged rollout controlled from the client and (b) a single Remote Config flag that lets you turn it all off in the next fetch interval.

Three preconditions before touching enforcement in Rork

Rork projects sit on top of Expo plus the React Native Firebase JS SDK, which means App Check has to be initialized through both layers. Before I let myself touch the Firebase console enforcement toggle, I check three things.

First, the @react-native-firebase/app-check package is on v18 or newer. v17 had an irritating intermittent initialization issue on iOS where the AppAttest provider would silently fail to obtain its first token, which left the app permanently in an "unverified" state on cold start.

Second, after expo prebuild, the iOS AppDelegate.swift calls the App Check provider factory before Firebase.configure(). The order matters. If Firebase.configure() runs first, the App Check internal listener that fires on the initial token fetch can be missed and you end up unverified until the next backoff.

Third, on Android the Play Integrity API is actually marked "in use" on the Play Console side. Picking Play Integrity in the Firebase console is necessary but not sufficient. Without the Play Console flag, the device will fall through to the unverified branch every time.

If any of those is wrong, no amount of rollback at the Firebase console level will resolve the symptoms, which is why I keep this as a hard preflight checklist.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦A four-stage rollout (0% / 10% / 50% / 100%) driven by Remote Config that lets you compare crash-free sessions between enforced and non-enforced cohorts before flipping the whole base
✦Three concrete failure modes where App Check silently killed Crashlytics and Realtime Database traffic in a live AdMob app, plus how to detect each one within a day
✦An emergency rollback design using a single `appCheckEmergencyDisable` Remote Config flag and a Cloud Functions bypass route that brings production back in roughly three minutes
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

⬡ Dev Tools2026-06-12
Building a Developer Debug Menu Into Your Rork App — Verify Ads, Purchases, and Remote Config Before Release
A production-safe developer debug menu for Rork apps — switch environments, force test ads, simulate entitlements, and override Remote Config, with working TypeScript code and the pitfalls I hit running six apps.
⬡ Dev Tools2026-05-16
Migrating Firebase CocoaPods to SPM in Rork Max Apps
Firebase Apple SDK's CocoaPods distribution ends in October 2026. Here's a detailed migration log from moving 4 Rork Max iOS apps to Swift Package Manager — including dSYM failures, module errors, and the Dropbox conflict copy problem you'll definitely hit.
⬡ Dev Tools2026-05-08
A Phased Release Strategy for Rork Apps — How I Combine iOS Phased Release, Android Staged Rollout, and OTA Hotfixes for a Production That Doesn't Break
How to protect a Rork app's production with three layers of safety: iOS Phased Release, Android Staged Rollout, and EAS Update OTA hotfixes — with the numeric thresholds I use to pause a rollout, a Sentry monitor, and the App Store Connect API call that pauses a phased release from your phone.