diff --git a/README.md b/README.md index 54a3858..9aade05 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Welcome to **FriendlyMeals**, an app that demonstrates how to integrate Firebase - **Firebase Authentication**: Learn how to keep your user's data safe with Firebase Authentication. - **Cloud Storage**: Learn how to store images in Cloud Storage, and how to display them in a Jetpack Compose UI. - **Remote Config**: Learn how to change the behavior and appearance of your app remotely with Remote Config. +- **App Check**: Learn how to protect your app backend from abuse with App Check. - **Upcoming**: More Firebase features will be added soon! ## 🛠️ Getting Started @@ -41,9 +42,28 @@ Welcome to **FriendlyMeals**, an app that demonstrates how to integrate Firebase 1. During the "Add app" workflow, **download the `google-services.json` file**. - Move this file into this directory of the app: `FriendlyMeals-Android/app`. - If you didn't download this file during the "Add app" workflow, you can always [obtain it later](https://support.google.com/firebase/answer/7015592). + +1. **Enable Firebase services in the Firebase console** + - Go to the [**Firebase Authentication**](https://console.firebase.google.com/project/_/authentication/?useAutoProject=true) section of the console, enable the service and choose the Anonymous authentication method. + - Go to the [**Firestore**](https://console.firebase.google.com/project/_/firestore/?useAutoProject=true) section of the console and enable Firestore Enterprise edition. + - Go to the [**Firebase AI Logic**](https://console.firebase.google.com/project/_/ailogic/?useAutoProject=true) section of the console and enable the Gemini Developer API. + - Go to the [**App Check**](https://console.firebase.google.com/project/_/appcheck/?useAutoProject=true) section of the console, enable this service, and register your Android app using the Play Integrity provider (you'll need to provide the SHA-256 fingerprint of your app's signing certificate). + - Go to the [**Remote Config**](https://console.firebase.google.com/project/_/config/?useAutoProject=true) section of the console and enable this service. + - Go to the [**Firebase Storage**](https://console.firebase.google.com/project/_/storage/?useAutoProject=true) section of the console and enable this service (you'll need to set up a billing account since this service is only available on the Blaze plan). 1. **Run the app** - Build and run in Android Studio on an Android emulator or physical device. + +1. **Set up App Check** + - Once your app is running on the emulator, look for the App Check debug token in your logs, and copy it. + - Then, in the Firebase console, go to the [Security > App Check > Apps tab](https://console.firebase.google.com/project/_/appcheck/apps/?useAutoProject=true) and locate your Android app. + - Click the three-dot menu and select **Manage debug tokens**. + - Paste your token in the "value" field and save it. + +The log will be similar to this: + + DebugAppCheckProvider: Enter this debug secret into the allow list + in the Firebase Console for your project: 123a4567-b89c-12d3-e456-789012345678 ## 🤝 Contributing diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 71fc31c..8d61ee0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -37,6 +37,7 @@ android { } buildFeatures { compose = true + buildConfig = true } } @@ -65,6 +66,8 @@ dependencies { implementation(platform(libs.firebase.bom)) implementation(libs.firebase.ai) implementation(libs.firebase.ai.ondevice) + implementation(libs.firebase.appcheck.debug) + implementation(libs.firebase.appcheck.playintegrity) implementation(libs.firebase.config) implementation(libs.firebase.auth) implementation(libs.firebase.storage) diff --git a/app/src/main/java/com/google/firebase/example/friendlymeals/MainActivity.kt b/app/src/main/java/com/google/firebase/example/friendlymeals/MainActivity.kt index 5b2aff3..6fe0ab7 100644 --- a/app/src/main/java/com/google/firebase/example/friendlymeals/MainActivity.kt +++ b/app/src/main/java/com/google/firebase/example/friendlymeals/MainActivity.kt @@ -21,6 +21,10 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navigation import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel +import com.google.firebase.Firebase +import com.google.firebase.appcheck.appCheck +import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory +import com.google.firebase.appcheck.playintegrity.PlayIntegrityAppCheckProviderFactory import com.google.firebase.example.friendlymeals.ui.generate.GenerateRoute import com.google.firebase.example.friendlymeals.ui.generate.GenerateScreen import com.google.firebase.example.friendlymeals.ui.groceryList.GroceryListRoute @@ -39,6 +43,7 @@ import com.google.firebase.example.friendlymeals.ui.scanMeal.ScanMealRoute import com.google.firebase.example.friendlymeals.ui.scanMeal.ScanMealScreen import com.google.firebase.example.friendlymeals.ui.shared.BottomNavBar import com.google.firebase.example.friendlymeals.ui.theme.FriendlyMealsTheme +import com.google.firebase.initialize import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -48,6 +53,7 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) enableEdgeToEdge() setSoftInputMode() + initializeAppCheck() setContent { val scope = rememberCoroutineScope() @@ -168,4 +174,16 @@ class MainActivity : ComponentActivity() { private fun setSoftInputMode() { window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING) } + + private fun initializeAppCheck() { + if (BuildConfig.DEBUG) { + Firebase.appCheck.installAppCheckProviderFactory( + DebugAppCheckProviderFactory.getInstance() + ) + } else { + Firebase.appCheck.installAppCheckProviderFactory( + PlayIntegrityAppCheckProviderFactory.getInstance() + ) + } + } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cf7a082..55283e5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,9 +2,8 @@ agp = "9.2.1" coilCompose = "2.7.0" exifinterface = "1.4.2" -firebaseAi = "17.13.0" -firebaseAiOndevice = "16.0.0-beta03" -firebaseBom = "34.15.0" +firebaseAiOndevice = "16.0.0-beta04" +firebaseBom = "34.17.0" kotlin = "2.3.21" coreKtx = "1.18.0" junit = "4.13.2" @@ -13,7 +12,7 @@ espressoCore = "3.7.0" lifecycleRuntimeKtx = "2.10.0" activityCompose = "1.13.0" composeBom = "2026.05.00" -googleServices = "4.4.4" +googleServices = "4.5.0" googleHilt = "2.59.2" googleKotlinKsp = "2.3.2" hiltAndroidCompiler = "2.59.2" @@ -31,8 +30,10 @@ playServicesLocation = "21.3.0" androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-exifinterface = { module = "androidx.exifinterface:exifinterface", version.ref = "exifinterface" } coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" } -firebase-ai = { module = "com.google.firebase:firebase-ai", version.ref = "firebaseAi" } +firebase-ai = { module = "com.google.firebase:firebase-ai"} firebase-ai-ondevice = { module = "com.google.firebase:firebase-ai-ondevice", version.ref = "firebaseAiOndevice" } +firebase-appcheck-debug = { module = "com.google.firebase:firebase-appcheck-debug" } +firebase-appcheck-playintegrity = { module = "com.google.firebase:firebase-appcheck-playintegrity" } firebase-auth = { module = "com.google.firebase:firebase-auth" } firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" } firebase-config = { module = "com.google.firebase:firebase-config" }