firebase / firebase-android-sdk

Firebase Android SDK
https://firebase.google.com
Apache License 2.0
2.23k stars 565 forks source link

[AppCheck] Invalid requests with Cloud Firestore #5190

Closed svenjacobs closed 10 months ago

svenjacobs commented 11 months ago

[REQUIRED] Step 2: Describe your environment

[REQUIRED] Step 3: Describe the problem

We're trying to set up AppCheck but have about 70% of invalid requests for Firestore. We assume these are requests from Android while iOS works.

Screenshot 2023-07-24 at 08 11 10



One thing that is maybe different from a default setup is that we configure the Firebase instance in code, not via google-services.json.

Steps to reproduce:

????

Relevant Code:

Initializing AppCheck:

class FirebaseAppCheckInitializer : Initializer<Unit> {

    @EntryPoint
    @InstallIn(SingletonComponent::class)
    interface FirebaseAppCheckInitializerEntryPoint {

        val firebaseAppCheck: FirebaseAppCheck
    }

    override fun create(context: Context) {
        val entryPoint = EntryPointAccessors.fromApplication<FirebaseAppCheckInitializerEntryPoint>(context)

        entryPoint.firebaseAppCheck.installAppCheckProviderFactory(
            PlayIntegrityAppCheckProviderFactory.getInstance(),
            true,
        )
    }

    override fun dependencies() = emptyList<Class<Initializer<*>>>()
}

Providing FirebaseAppCheck instance via Hilt:

@Module
@InstallIn(SingletonComponent::class)
object FirebaseModule {

    @Provides
    @Singleton
    fun provideFirebaseApp(@ApplicationContext context: Context): FirebaseApp {
        // Values taken from downloaded google-services.json
        val options = FirebaseOptions.Builder()
            .setProjectId("")
            .setApplicationId("")
            .setApiKey("")
            .setDatabaseUrl("")
            .setGcmSenderId("")
            .setStorageBucket("")
            .build()

        return runCatching { Firebase.app }
            .getOrElse { Firebase.initialize(context, options) }
    }

    @Provides
    fun provideFirebaseAppCheck(firebaseApp: FirebaseApp): FirebaseAppCheck =
        Firebase.appCheck(firebaseApp)

    @Provides
    fun provideFirebaseFirestore(firebaseApp: FirebaseApp): FirebaseFirestore = 
        Firebase.firestore(firebaseApp)
}
google-oss-bot commented 11 months ago

I found a few problems with this issue:

argzdev commented 11 months ago

Hi @svenjacobs, thanks for reaching out. I tried a mixture of scenarios either using a google-services.json or with a Firebase instance, it still seems that PlayIntegrityAppCheckProviderFactory won't work. It works when using the DebugAppCheckProviderFactory.getInstance(), so it means that the setup with hilt and initializer is correct. Let me consult with some engineers and see what we can do here.

Tracking internally on: b/293633326

svenjacobs commented 11 months ago

Thanks @argzdev for your feedback. I'm glad you can reproduce this. Looking forward to your findings.

argzdev commented 11 months ago

Hi @svenjacobs, while we were investigating for the past few days, I started receiving verified requests today (without changing any of the SHA256 or Google Play Console settings). Could you check on your side if yours is also working? If so, then this could be due to an outage on Play Integrity side, and AppCheck itself doesn't have any issues.

svenjacobs commented 11 months ago

@argzdev Unfortunately I don't see any improvements of the numbers. We have this problem for months now.

argzdev commented 11 months ago

Hi @svenjacobs, after more further testing, one specific change I did was using a physical device for testing which allowed me to get verified requests with your code setup. In your case, obviously this doesn't apply since you've already have a multitude of requests from a wide range of devices. That said, could you recheck if you have a following checklist complete below:

  1. App signing key SHA256 is added to Firebase Console
  2. Upload key certificate SHA256 is added to Firebase Console (I'm not sure if this is a requirement, you'll have to check with Play Integrity team)
  3. Release keystore SHA256 is added to Firebase Console (This might be the same as your App signing)
  4. Debug keystore SHA256 is added to Firebase Console
    • After steps 1 to 4, In my case, a total of 3 SHA256 keys are added to my Firebase Console.
  5. In your Google Play Console > Setup > App Signing, under Integrity API, make sure your app is linked with your Google Cloud project
  6. Make sure your app is registered in the Firebase Console App Check section Screenshot 2023-08-07 at 9 06 17 PM

Now, once you've verified everything is correct, and AppCheck is still not working, then this would mean a broken connection between AppCheck and Play Integrity. That said, you'll have to reach out to Play Integrity team since they'll be able to view your project details and configuration from the backend. You can reach out on their link here.

Let me know if this helps. Thanks!

google-oss-bot commented 10 months ago

Hey @svenjacobs. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

svenjacobs commented 10 months ago
  1. App signing key SHA256 is added to Firebase Console

✅ That is correct.

  1. Upload key certificate SHA256 is added to Firebase Console (I'm not sure if this is a requirement, you'll have to check with Play Integrity team)

✅ I doubt this will change anything because I had it there before but I added it again.

  1. Release keystore SHA256 is added to Firebase Console (This might be the same as your App signing)

✅ Yes, it is the same since we use App Signing.

  1. Debug keystore SHA256 is added to Firebase Console

❌ Since we only have a release app in the Firebase project, I did not add the debug key certificate.

  • After steps 1 to 4, In my case, a total of 3 SHA256 keys are added to my Firebase Console.

✅ I have two: App signing and upload key certificate SHA256

  1. In your Google Play Console > Setup > App Signing, under Integrity API, make sure your app is linked with your Google Cloud project

✅ The Cloud project is linked and I see lots of successful Integrity API calls in Play Console

  1. Make sure your app is registered in the Firebase Console App Check section

✅ Play Integrity as well as the old SafetyNet are registered / enabled

argzdev commented 10 months ago

Thanks for the extra details, @svenjacobs. In this case, since we've verified that testing your code snippet works with the SDK, then it shows no issue with how the SDK works. Most certainly the issue now is with the connection with the backend, that said there's nothing else we can do on our side. You'll have to reach out to Play Integrity team since they'll be able to view your project details and configuration from the backend. You can reach out on their link here. You may also refer to them this GitHub thread for more context on what we've investigated. Thanks!

svenjacobs commented 10 months ago

Thanks for your support! I contacted the Play Integrity support 🤞🏼