Firebase App Check
Firebase App Check verifies that /claim requests come from your genuine app — not emulators, modified builds, or scripts. BitEasy supports Firebase App Check using App Attest on iOS and Play Integrity on Android.
Why App Check?
Section titled “Why App Check?”BitEasy attributes revenue to the partner who referred the install. That attribution chain is only as trustworthy as the /claim request that starts it — if someone can forge a claim, they can steal credit (and payouts) for installs they never referred.
Without attestation, nothing stops a bad actor from:
- Scripting fake claims — hitting
/claimwith fabricated install IDs to hijack attribution for real users - Running modified app builds — injecting a hardcoded partner code so every install attributes to them
- Using emulators at scale — generating thousands of “installs” that look legitimate to the API
App Check closes this gap by requiring every /claim request to include a cryptographic token issued by Apple (App Attest) or Google (Play Integrity). These tokens prove:
- The request comes from your unmodified app binary — not a script, proxy, or tampered build
- The app is running on a real device — not an emulator or rooted environment
- The app was distributed through official channels — App Store, TestFlight, or Google Play
BitEasy’s backend verifies the token against Firebase’s public keys before processing the claim. Invalid or missing tokens are rejected with a 403, so forged attributions never reach the database.
The result: every attributed install maps to a real user who opened your real app on a real device — and partner payouts reflect genuine referrals.
Prerequisites
Section titled “Prerequisites”- A Firebase project (create one at console.firebase.google.com)
- Your app registered in Firebase with the correct bundle ID (iOS) and package name (Android)
- Your app published to at least TestFlight (iOS) or Internal Testing (Android)
1. Firebase Console Setup
Section titled “1. Firebase Console Setup”-
Create a Firebase project (or use an existing one) at console.firebase.google.com.
-
Register your iOS app:
- Click Add app > iOS
- Enter your Bundle ID (e.g.,
com.example.myapp) - Download
GoogleService-Info.plist
-
Register your Android app:
- Click Add app > Android
- Enter your Package name (e.g.,
com.example.myapp) - For the SHA-256 fingerprint, you need both your upload key and app signing key (see SHA Fingerprints below)
- Download
google-services.json
-
Enable App Check providers:
- Go to App Check in the left sidebar
- For your iOS app: select App Attest and enter your Apple Team ID (found at developer.apple.com/account)
- For your Android app: select Play Integrity
SHA Fingerprints (Android)
Section titled “SHA Fingerprints (Android)”If you use Play App Signing (enabled by default for new apps), Google re-signs your APK with a different key before distributing to users. You must add both fingerprints to Firebase:
| Key | Where to find it | Purpose |
|---|---|---|
| Upload key | Your local keystore: keytool -list -v -keystore your-keystore.jks | Verifies uploads to Play Console |
| App signing key | Play Console > Setup > App signing | What’s actually on user devices |
Add both SHA-256 fingerprints in Firebase Console > Project Settings > your Android app.
Link Firebase to Google Play
Section titled “Link Firebase to Google Play”For Play Integrity to work, your Firebase project must be linked to Google Play:
- Open Google Play Console > your app > Setup > App integrity
- Under Link a Cloud project, select the same project as your Firebase project
- Enable the Play Integrity API in Google Cloud Console > APIs & Services > Enable APIs
2. Configure BitEasy
Section titled “2. Configure BitEasy”In the BitEasy dashboard:
- Go to your app’s Settings > Attestation
- Select Firebase as the provider
- Enter your Firebase Project Number (found in Firebase Console > Project Settings > General)
3. Mobile App Integration
Section titled “3. Mobile App Integration”The example below uses Expo with React Native Firebase. If you’re using a different environment (native iOS/Android, Flutter, Unity, etc.), refer to the Firebase App Check documentation for platform-specific setup. The BitEasy integration is the same regardless of platform — attach the token via the X-Firebase-AppCheck header on your /claim requests. That’s the only header BitEasy looks for.
Install Dependencies
Section titled “Install Dependencies”npm install @react-native-firebase/app @react-native-firebase/app-checkbun add @react-native-firebase/app @react-native-firebase/app-checkAdd Config Files
Section titled “Add Config Files”Place the Firebase config files in your project root:
- iOS:
GoogleService-Info.plist - Android:
google-services.json
Reference them in your app.json (Expo):
{ "expo": { "ios": { "googleServicesFile": "./GoogleService-Info.plist" }, "android": { "googleServicesFile": "./google-services.json" }, "plugins": [ "@react-native-firebase/app", "@react-native-firebase/app-check", [ "expo-build-properties", { "ios": { "useFrameworks": "static" } } ] ] }}Initialize App Check
Section titled “Initialize App Check”Create an initialization module that runs at app startup:
import { getApp } from "@react-native-firebase/app";import { type AppCheck, getToken, initializeAppCheck,} from "@react-native-firebase/app-check";
const initPromise: Promise<AppCheck | null> = initializeAppCheck(getApp(), { provider: { providerOptions: { android: { provider: "playIntegrity" }, apple: { provider: "appAttest" }, }, }, isTokenAutoRefreshEnabled: true,}).catch((error) => { console.error("Firebase App Check initialization failed", error); return null;});
export async function getAppCheckToken(): Promise<string | null> { const instance = await initPromise; if (!instance) return null; const { token } = await getToken(instance); return token;}Import this module in your root layout so it initializes early:
// app/_layout.tsx (or your entry point)import "@/utils/app-check";Attach Token to /claim Requests
Section titled “Attach Token to /claim Requests”Include the App Check token as the X-Firebase-AppCheck header on every /claim request:
import { getAppCheckToken } from "./app-check";
const appCheckToken = await getAppCheckToken();
fetch("https://api.biteasy.co/api/v1/claim", { method: "POST", headers: { "Content-Type": "application/json", ...(appCheckToken && { "X-Firebase-AppCheck": appCheckToken }), }, body: JSON.stringify({ appId: "your-app-id", installId: "user-install-id", platform: "ios", claimCode: "B1-ABCD1234", }),});Apple Provider Options
Section titled “Apple Provider Options”| Provider | Minimum iOS | Description |
|---|---|---|
appAttest | iOS 14+ (A12 chip) | Strongest attestation, uses Apple’s App Attest API |
deviceCheck | iOS 11+ | Broader device support, uses DeviceCheck API |
appAttestWithDeviceCheckFallback | iOS 11+ | Uses App Attest when available, falls back to DeviceCheck on older devices |
We recommend appAttest for production apps targeting iOS 14+. Use appAttestWithDeviceCheckFallback if you need to support older devices.
Troubleshooting
Section titled “Troubleshooting””App attestation failed” (403) on Android
Section titled “”App attestation failed” (403) on Android”- Check SHA fingerprints — Ensure both your upload key and app signing key SHA-256 are registered in Firebase Console
- Verify Play Console linking — The correct Firebase/GCP project must be linked in Play Console > Setup > App integrity
- Enable Play Integrity API — Must be enabled in Google Cloud Console for your project
- Sideloaded APKs won’t work — Play Integrity requires the app to be installed from Google Play (internal testing track is fine)
“App attestation failed” (403) on iOS
Section titled ““App attestation failed” (403) on iOS”- Check Team ID — Must be entered correctly in Firebase Console > App Check > your iOS app
- Device compatibility — App Attest requires iOS 14+ and A12 chip or later. Use
appAttestWithDeviceCheckFallbackfor broader support - TestFlight builds work — App Attest works with TestFlight and App Store builds, but not Xcode direct installs
Token is null
Section titled “Token is null”- Initialization race condition — Ensure you
awaitthe init promise before callinggetToken. The example above handles this correctly - Firebase config missing — Verify
GoogleService-Info.plistandgoogle-services.jsonare in the correct locations and referenced inapp.json - Native rebuild required — After adding Firebase dependencies, you must rebuild the native app (prebuild + build). Hot reload is not sufficient
Next Steps
Section titled “Next Steps”- App Settings — Attestation — Enable attestation in the BitEasy dashboard
- App Integration — Complete your
/claimintegration