Showing preview only (1,724K chars total). Download the full file or copy to clipboard to get everything.
Repository: firebase/quickstart-android
Branch: master
Commit: 7da89ea2e750
Files: 658
Total size: 1.5 MB
Directory structure:
gitextract_q82ekbdt/
├── .editorconfig
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── config.yml
│ │ └── quickstart_issue.md
│ └── workflows/
│ └── android.yml
├── .gitignore
├── .google/
│ └── packaging.yaml
├── .opensource/
│ └── project.json
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── admob/
│ ├── .gitignore
│ ├── .google/
│ │ └── packaging.yaml
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── samples/
│ │ │ └── quickstart/
│ │ │ └── admobexample/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── FirstFragment.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── SecondFragment.java
│ │ │ └── kotlin/
│ │ │ ├── FirstFragment.kt
│ │ │ ├── MainActivity.kt
│ │ │ └── SecondFragment.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ ├── fragment_first.xml
│ │ │ └── fragment_second.xml
│ │ ├── navigation/
│ │ │ ├── nav_graph_java.xml
│ │ │ └── nav_graph_kotlin.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── analytics/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── analytics/
│ │ │ └── MainActivityTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── analytics/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── ImageFragment.java
│ │ │ │ ├── ImageInfo.java
│ │ │ │ └── MainActivity.java
│ │ │ └── kotlin/
│ │ │ ├── ImageFragment.kt
│ │ │ ├── ImageInfo.kt
│ │ │ └── MainActivity.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ └── circle.xml
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ └── fragment_main.xml
│ │ ├── menu/
│ │ │ └── main.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-v21/
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── appdistribution/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── appdistributionquickstart/
│ │ │ └── InstrumentedTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── appdistributionquickstart/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ └── MainActivity.java
│ │ │ └── kotlin/
│ │ │ └── KotlinMainActivity.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ └── ic_launcher_background.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── auth/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── auth/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── AnonymousAuthFragment.java
│ │ │ │ ├── BaseActivity.java
│ │ │ │ ├── BaseFragment.java
│ │ │ │ ├── ChooserFragment.java
│ │ │ │ ├── CustomAuthFragment.java
│ │ │ │ ├── EmailPasswordFragment.java
│ │ │ │ ├── FacebookLoginFragment.java
│ │ │ │ ├── FirebaseUIFragment.java
│ │ │ │ ├── GenericIdpFragment.java
│ │ │ │ ├── GoogleSignInFragment.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MultiFactorEnrollFragment.java
│ │ │ │ ├── MultiFactorFragment.java
│ │ │ │ ├── MultiFactorSignInFragment.java
│ │ │ │ ├── MultiFactorUnenrollFragment.java
│ │ │ │ ├── PasswordlessActivity.java
│ │ │ │ ├── PhoneAuthFragment.java
│ │ │ │ └── TokenBroadcastReceiver.java
│ │ │ └── kotlin/
│ │ │ ├── AnonymousAuthFragment.kt
│ │ │ ├── BaseActivity.kt
│ │ │ ├── BaseFragment.kt
│ │ │ ├── ChooserFragment.kt
│ │ │ ├── CustomAuthFragment.kt
│ │ │ ├── EmailPasswordFragment.kt
│ │ │ ├── FacebookLoginFragment.kt
│ │ │ ├── FirebaseUIFragment.kt
│ │ │ ├── GenericIdpFragment.kt
│ │ │ ├── GoogleSignInFragment.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── MultiFactorEnrollFragment.kt
│ │ │ ├── MultiFactorFragment.kt
│ │ │ ├── MultiFactorSignInFragment.kt
│ │ │ ├── MultiFactorUnenrollFragment.kt
│ │ │ ├── PasswordlessActivity.kt
│ │ │ ├── PhoneAuthFragment.kt
│ │ │ └── TokenBroadcastReceiver.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_passwordless.xml
│ │ │ ├── fragment_anonymous_auth.xml
│ │ │ ├── fragment_chooser.xml
│ │ │ ├── fragment_custom.xml
│ │ │ ├── fragment_emailpassword.xml
│ │ │ ├── fragment_facebook.xml
│ │ │ ├── fragment_firebase_ui.xml
│ │ │ ├── fragment_generic_idp.xml
│ │ │ ├── fragment_google.xml
│ │ │ ├── fragment_multi_factor.xml
│ │ │ ├── fragment_multi_factor_sign_in.xml
│ │ │ ├── fragment_passwordless.xml
│ │ │ ├── fragment_phone_auth.xml
│ │ │ └── item_spinner_list.xml
│ │ ├── navigation/
│ │ │ ├── nav_graph_java.xml
│ │ │ └── nav_graph_kotlin.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── ids.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-land/
│ │ │ └── dimens.xml
│ │ ├── values-v21/
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── settings.gradle.kts
│ └── web/
│ └── auth.html
├── build.gradle.kts
├── build_pull_request.sh
├── config/
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── samples/
│ │ │ └── quickstart/
│ │ │ └── config/
│ │ │ └── MainActivityTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── samples/
│ │ │ └── quickstart/
│ │ │ └── config/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ └── MainActivity.java
│ │ │ └── kotlin/
│ │ │ └── MainActivity.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-w820dp/
│ │ │ └── dimens.xml
│ │ └── xml/
│ │ └── remote_config_defaults.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── copy_mock_google_services_json.sh
├── crash/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ ├── src/
│ │ │ ├── androidTest/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── google/
│ │ │ │ └── samples/
│ │ │ │ └── quickstart/
│ │ │ │ └── crash/
│ │ │ │ └── MainActivityTest.java
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── google/
│ │ │ │ └── samples/
│ │ │ │ └── quickstart/
│ │ │ │ └── crash/
│ │ │ │ ├── EntryChoiceActivity.kt
│ │ │ │ ├── java/
│ │ │ │ │ ├── CustomKeySamples.java
│ │ │ │ │ └── MainActivity.java
│ │ │ │ └── kotlin/
│ │ │ │ ├── CustomKeySamples.kt
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── layout/
│ │ │ │ └── activity_main.xml
│ │ │ ├── values/
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ └── values-w820dp/
│ │ │ └── dimens.xml
│ │ └── test-proguard-rules.pro
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── database/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── database/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── BaseFragment.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MainFragment.java
│ │ │ │ ├── NewPostFragment.java
│ │ │ │ ├── PostDetailFragment.java
│ │ │ │ ├── SignInFragment.java
│ │ │ │ ├── listfragments/
│ │ │ │ │ ├── MyPostsFragment.java
│ │ │ │ │ ├── MyTopPostsFragment.java
│ │ │ │ │ ├── PostListFragment.java
│ │ │ │ │ └── RecentPostsFragment.java
│ │ │ │ ├── models/
│ │ │ │ │ ├── Comment.java
│ │ │ │ │ ├── Post.java
│ │ │ │ │ └── User.java
│ │ │ │ └── viewholder/
│ │ │ │ ├── CommentViewHolder.java
│ │ │ │ └── PostViewHolder.java
│ │ │ └── kotlin/
│ │ │ ├── BaseFragment.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── MainFragment.kt
│ │ │ ├── NewPostFragment.kt
│ │ │ ├── PostDetailFragment.kt
│ │ │ ├── SignInFragment.kt
│ │ │ ├── listfragments/
│ │ │ │ ├── MyPostsFragment.kt
│ │ │ │ ├── MyTopPostsFragment.kt
│ │ │ │ ├── PostListFragment.kt
│ │ │ │ └── RecentPostsFragment.kt
│ │ │ ├── models/
│ │ │ │ ├── Comment.kt
│ │ │ │ ├── Post.kt
│ │ │ │ └── User.kt
│ │ │ └── viewholder/
│ │ │ ├── CommentViewHolder.kt
│ │ │ └── PostViewHolder.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ ├── fragment_all_posts.xml
│ │ │ ├── fragment_main.xml
│ │ │ ├── fragment_new_post.xml
│ │ │ ├── fragment_post_detail.xml
│ │ │ ├── fragment_sign_in.xml
│ │ │ ├── include_post_author.xml
│ │ │ ├── include_post_text.xml
│ │ │ ├── item_comment.xml
│ │ │ └── item_post.xml
│ │ ├── menu/
│ │ │ └── menu_main.xml
│ │ ├── navigation/
│ │ │ ├── nav_graph_java.xml
│ │ │ └── nav_graph_kotlin.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-v21/
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── dataconnect/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── example/
│ │ │ └── dataconnect/
│ │ │ ├── MainActivity.kt
│ │ │ ├── feature/
│ │ │ │ ├── actordetail/
│ │ │ │ │ ├── ActorDetailScreen.kt
│ │ │ │ │ ├── ActorDetailUIState.kt
│ │ │ │ │ └── ActorDetailViewModel.kt
│ │ │ │ ├── moviedetail/
│ │ │ │ │ ├── MovieDetailScreen.kt
│ │ │ │ │ ├── MovieDetailUIState.kt
│ │ │ │ │ ├── MovieDetailViewModel.kt
│ │ │ │ │ └── UserReviews.kt
│ │ │ │ ├── movies/
│ │ │ │ │ ├── MoviesScreen.kt
│ │ │ │ │ ├── MoviesUIState.kt
│ │ │ │ │ └── MoviesViewModel.kt
│ │ │ │ ├── profile/
│ │ │ │ │ ├── AuthScreen.kt
│ │ │ │ │ ├── ProfileScreen.kt
│ │ │ │ │ ├── ProfileUIState.kt
│ │ │ │ │ └── ProfileViewModel.kt
│ │ │ │ └── search/
│ │ │ │ └── Navigation.kt
│ │ │ └── ui/
│ │ │ ├── components/
│ │ │ │ ├── ActorsList.kt
│ │ │ │ ├── ErrorCard.kt
│ │ │ │ ├── LoadingScreen.kt
│ │ │ │ ├── MoviesList.kt
│ │ │ │ ├── ReviewCard.kt
│ │ │ │ └── ToggleButton.kt
│ │ │ └── theme/
│ │ │ ├── Color.kt
│ │ │ ├── Theme.kt
│ │ │ └── Type.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── firebase_data_connect.xml
│ │ │ └── ic_launcher_background.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── themes.xml
│ │ └── xml/
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ ├── build.gradle.kts
│ ├── dataconnect/
│ │ ├── dataconnect.yaml
│ │ ├── movie-connector/
│ │ │ ├── connector.yaml
│ │ │ ├── mutations.gql
│ │ │ └── queries.gql
│ │ ├── moviedata_insert.gql
│ │ └── schema/
│ │ └── schema.gql
│ ├── firebase.json
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── dynamiclinks/
│ └── README.md
├── firebase-ai/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── ai/
│ │ │ ├── MainActivity.kt
│ │ │ ├── feature/
│ │ │ │ ├── live/
│ │ │ │ │ ├── BidiViewModel.kt
│ │ │ │ │ ├── StreamAudioViewModel.kt
│ │ │ │ │ └── StreamVideoViewModel.kt
│ │ │ │ ├── media/
│ │ │ │ │ └── imagen/
│ │ │ │ │ ├── ImagenGenerationViewModel.kt
│ │ │ │ │ ├── ImagenInpaintingViewModel.kt
│ │ │ │ │ ├── ImagenOutpaintingViewModel.kt
│ │ │ │ │ ├── ImagenStyleTransferViewModel.kt
│ │ │ │ │ ├── ImagenSubjectReferenceViewModel.kt
│ │ │ │ │ ├── ImagenTemplateViewModel.kt
│ │ │ │ │ └── ImagenViewModel.kt
│ │ │ │ └── text/
│ │ │ │ ├── AudioSummarizationViewModel.kt
│ │ │ │ ├── AudioTranslationViewModel.kt
│ │ │ │ ├── ChatViewModel.kt
│ │ │ │ ├── CourseRecommendationsViewModel.kt
│ │ │ │ ├── DocumentComparisonViewModel.kt
│ │ │ │ ├── GoogleSearchGroundingViewModel.kt
│ │ │ │ ├── ImageBlogCreatorViewModel.kt
│ │ │ │ ├── ImageGenerationViewModel.kt
│ │ │ │ ├── ServerPromptTemplateViewModel.kt
│ │ │ │ ├── SvgViewModel.kt
│ │ │ │ ├── ThinkingChatViewModel.kt
│ │ │ │ ├── TranslationViewModel.kt
│ │ │ │ ├── TravelTipsViewModel.kt
│ │ │ │ ├── VideoHashtagGeneratorViewModel.kt
│ │ │ │ ├── VideoSummarizationViewModel.kt
│ │ │ │ ├── WeatherChatViewModel.kt
│ │ │ │ └── functioncalling/
│ │ │ │ └── WeatherRepository.kt
│ │ │ └── ui/
│ │ │ ├── CameraView.kt
│ │ │ ├── ChatScreen.kt
│ │ │ ├── ChatUiState.kt
│ │ │ ├── ImagenScreen.kt
│ │ │ ├── ImagenUiState.kt
│ │ │ ├── ServerPromptScreen.kt
│ │ │ ├── ServerPromptUiState.kt
│ │ │ ├── StreamRealtimeScreen.kt
│ │ │ ├── StreamRealtimeVideoScreen.kt
│ │ │ ├── SvgScreen.kt
│ │ │ ├── SvgUiState.kt
│ │ │ ├── navigation/
│ │ │ │ ├── FirebaseAISamples.kt
│ │ │ │ ├── MainMenuScreen.kt
│ │ │ │ └── Sample.kt
│ │ │ └── theme/
│ │ │ ├── Color.kt
│ │ │ ├── Theme.kt
│ │ │ └── Type.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── round_arrow_drop_down_24.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── themes.xml
│ │ └── xml/
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── firestore/
│ ├── .gitignore
│ ├── CONTRIBUTING.md
│ ├── LICENSE
│ ├── README.md
│ ├── accounts.json
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ ├── src/
│ │ │ ├── androidTest/
│ │ │ │ └── AndroidManifest.xml
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── google/
│ │ │ │ └── firebase/
│ │ │ │ └── example/
│ │ │ │ └── fireeats/
│ │ │ │ ├── EntryChoiceActivity.kt
│ │ │ │ ├── java/
│ │ │ │ │ ├── FilterDialogFragment.java
│ │ │ │ │ ├── Filters.java
│ │ │ │ │ ├── MainActivity.java
│ │ │ │ │ ├── MainFragment.java
│ │ │ │ │ ├── RatingDialogFragment.java
│ │ │ │ │ ├── RestaurantDetailFragment.java
│ │ │ │ │ ├── adapter/
│ │ │ │ │ │ ├── FirestoreAdapter.java
│ │ │ │ │ │ ├── RatingAdapter.java
│ │ │ │ │ │ └── RestaurantAdapter.java
│ │ │ │ │ ├── model/
│ │ │ │ │ │ ├── Rating.java
│ │ │ │ │ │ └── Restaurant.java
│ │ │ │ │ ├── util/
│ │ │ │ │ │ ├── RatingUtil.java
│ │ │ │ │ │ └── RestaurantUtil.java
│ │ │ │ │ └── viewmodel/
│ │ │ │ │ └── MainActivityViewModel.java
│ │ │ │ └── kotlin/
│ │ │ │ ├── FilterDialogFragment.kt
│ │ │ │ ├── Filters.kt
│ │ │ │ ├── MainActivity.kt
│ │ │ │ ├── MainFragment.kt
│ │ │ │ ├── RatingDialogFragment.kt
│ │ │ │ ├── RestaurantDetailFragment.kt
│ │ │ │ ├── adapter/
│ │ │ │ │ ├── FirestoreAdapter.kt
│ │ │ │ │ ├── RatingAdapter.kt
│ │ │ │ │ └── RestaurantAdapter.kt
│ │ │ │ ├── model/
│ │ │ │ │ ├── Rating.kt
│ │ │ │ │ └── Restaurant.kt
│ │ │ │ ├── util/
│ │ │ │ │ ├── RatingUtil.kt
│ │ │ │ │ └── RestaurantUtil.kt
│ │ │ │ └── viewmodel/
│ │ │ │ └── MainActivityViewModel.kt
│ │ │ └── res/
│ │ │ ├── anim/
│ │ │ │ ├── slide_in_from_left.xml
│ │ │ │ ├── slide_in_from_right.xml
│ │ │ │ ├── slide_out_to_left.xml
│ │ │ │ └── slide_out_to_right.xml
│ │ │ ├── drawable/
│ │ │ │ ├── bg_shadow.xml
│ │ │ │ ├── gradient_up.xml
│ │ │ │ ├── ic_add_white_24px.xml
│ │ │ │ ├── ic_arrow_back_white_24px.xml
│ │ │ │ ├── ic_close_white_24px.xml
│ │ │ │ ├── ic_fastfood_white_24dp.xml
│ │ │ │ ├── ic_filter_list_white_24px.xml
│ │ │ │ ├── ic_local_dining_white_24px.xml
│ │ │ │ ├── ic_monetization_on_white_24px.xml
│ │ │ │ ├── ic_place_white_24px.xml
│ │ │ │ ├── ic_restaurant_white_24px.xml
│ │ │ │ └── ic_sort_white_24px.xml
│ │ │ ├── layout/
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── dialog_filters.xml
│ │ │ │ ├── dialog_rating.xml
│ │ │ │ ├── fragment_main.xml
│ │ │ │ ├── fragment_restaurant_detail.xml
│ │ │ │ ├── item_rating.xml
│ │ │ │ └── item_restaurant.xml
│ │ │ ├── menu/
│ │ │ │ └── menu_main.xml
│ │ │ ├── navigation/
│ │ │ │ ├── nav_graph_java.xml
│ │ │ │ └── nav_graph_kotlin.xml
│ │ │ ├── values/
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ └── values-v21/
│ │ │ └── styles.xml
│ │ └── test-proguard-rules.pro
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── indexes.json
│ ├── settings.gradle.kts
│ └── test_setup.sh
├── functions/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ ├── src/
│ │ │ ├── androidTest/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── google/
│ │ │ │ └── samples/
│ │ │ │ └── quickstart/
│ │ │ │ └── functions/
│ │ │ │ ├── MainActivityTest.java
│ │ │ │ └── TestAddNumber.java
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── google/
│ │ │ │ └── samples/
│ │ │ │ └── quickstart/
│ │ │ │ └── functions/
│ │ │ │ ├── EntryChoiceActivity.kt
│ │ │ │ ├── java/
│ │ │ │ │ ├── FunctionsMessagingService.java
│ │ │ │ │ └── MainActivity.java
│ │ │ │ └── kotlin/
│ │ │ │ ├── FunctionsMessagingService.kt
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── layout/
│ │ │ │ └── activity_main.xml
│ │ │ ├── values/
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── values-w820dp/
│ │ │ │ └── dimens.xml
│ │ │ └── xml/
│ │ │ └── network_security_config.xml
│ │ └── test-proguard-rules.pro
│ ├── build.gradle.kts
│ ├── firebase.json
│ ├── functions/
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── package.json
│ │ └── sanitizer.js
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── settings.gradle.kts
│ └── test_setup.sh
├── gradle/
│ ├── libs.versions.toml
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── inappmessaging/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── fiamquickstart/
│ │ │ └── InstrumentedTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── fiamquickstart/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ └── MainActivity.java
│ │ │ └── kotlin/
│ │ │ └── KotlinMainActivity.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ └── ic_launcher_background.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── internal/
│ ├── chooserx/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── firebase/
│ │ │ └── example/
│ │ │ └── internal/
│ │ │ ├── BaseEntryChoiceActivity.java
│ │ │ ├── Choice.java
│ │ │ └── ChoiceAdapter.java
│ │ └── res/
│ │ └── layout/
│ │ ├── activity_entry_choice.xml
│ │ └── item_choice.xml
│ ├── lint/
│ │ ├── .gitignore
│ │ ├── bin/
│ │ │ ├── main/
│ │ │ │ └── com/
│ │ │ │ └── firebase/
│ │ │ │ └── lint/
│ │ │ │ ├── HungarianNotationDetector.kt
│ │ │ │ ├── InvalidImportDetector.kt
│ │ │ │ └── QuickstartIssueRegistry.kt
│ │ │ └── test/
│ │ │ └── com/
│ │ │ └── firebase/
│ │ │ └── lint/
│ │ │ └── InvalidImportDetectorTest.kt
│ │ ├── build.gradle.kts
│ │ └── src/
│ │ ├── main/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── firebase/
│ │ │ └── lint/
│ │ │ ├── HungarianNotationDetector.kt
│ │ │ ├── InvalidImportDetector.kt
│ │ │ └── QuickstartIssueRegistry.kt
│ │ └── test/
│ │ └── java/
│ │ └── com/
│ │ └── firebase/
│ │ └── lint/
│ │ └── InvalidImportDetectorTest.kt
│ └── lintchecks/
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── proguard-rules.pro
│ └── src/
│ └── main/
│ └── AndroidManifest.xml
├── messaging/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── fcm/
│ │ │ └── MainActivityEspressoTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── fcm/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MyFirebaseMessagingService.java
│ │ │ │ └── MyWorker.java
│ │ │ └── kotlin/
│ │ │ ├── MainActivity.kt
│ │ │ ├── MyFirebaseMessagingService.kt
│ │ │ └── MyWorker.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── mock-google-services.json
├── perf/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── assets/
│ │ │ └── default_content.txt
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── perfmon/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ └── MainActivity.java
│ │ │ └── kotlin/
│ │ │ └── MainActivity.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── scripts/
│ └── checksnippets.py
├── settings.gradle.kts
├── storage/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── firebasestorage/
│ │ │ ├── MainActivityTest.java
│ │ │ └── ServiceIdlingResource.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── firebasestorage/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MyBaseTaskService.java
│ │ │ │ ├── MyDownloadService.java
│ │ │ │ └── MyUploadService.java
│ │ │ └── kotlin/
│ │ │ ├── MainActivity.kt
│ │ │ ├── MyBaseTaskService.kt
│ │ │ ├── MyDownloadService.kt
│ │ │ └── MyUploadService.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ ├── menu/
│ │ │ └── menu_main.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-w820dp/
│ │ │ └── dimens.xml
│ │ └── xml/
│ │ └── file_paths.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
└── vertexai/
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
[*.{java,kt}]
max_line_length = 120
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: 🐞 Bug in the Firebase SDK
url: https://github.com/firebase/firebase-android-sdk/issues/new/choose
about: Do you think you have found a bug in the Firebase Android SDK?
- name: 🤖 MLKit On-Device Issues
url: https://github.com/googlesamples/mlkit
about: The MLKit on-device SDK has moved out of Firebase and the best place to get support is on their samples repository.
- name: 🔥 Firebase Support
url: https://firebase.google.com/support/
about: If you have an urgent issue with your app, please contact support.
================================================
FILE: .github/ISSUE_TEMPLATE/quickstart_issue.md
================================================
---
name: ⚠️ Issue with the quickstart code
about:
Are you having issues running the code in this repository?
---
<!-- DO NOT DELETE
validate_template=true
template_path=.github/ISSUE_TEMPLATE/quickstart_issue.md
-->
<!--
Are you in the right place?
* If you think you have found a **bug in the Firebase Android SDK** please file the issue here:
https://github.com/firebase/firebase-android-sdk
* If you are filing an issue about **FCM in the background** make sure to read [#4](https://github.com/firebase/quickstart-android/issues/4) and [#89](https://github.com/firebase/quickstart-android/issues/89) first!
-->
### Step 1: Describe your environment
* Android device: _____
* Android OS version: _____
* Google Play Services version: _____
* Firebase/Play Services SDK version: _____
### Step 2: Describe the problem:
#### Steps to reproduce:
1. _____
2. _____
3. _____
#### Observed Results:
* What happened? This could be a description, `logcat` output, etc.
#### Expected Results:
* What did you expect to happen?
#### Relevant Code:
```
// TODO(you): code here to reproduce the problem
```
================================================
FILE: .github/workflows/android.yml
================================================
name: Android CI
on:
pull_request:
push:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 17
- name: Install Node to use the Firebase CLI
uses: actions/setup-node@v6
with:
node-version: 24
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Check Snippets
run: python scripts/checksnippets.py
- name: Copy mock google_services.json
run: ./copy_mock_google_services_json.sh
- name: Build with Gradle (Pull Request)
run: ./build_pull_request.sh
if: github.event_name == 'pull_request'
- name: Build with Gradle (Push)
run: ./gradlew clean ktlint assemble
if: github.event_name != 'pull_request'
================================================
FILE: .gitignore
================================================
.gradle
local.properties
.idea
build/
.DS_Store
*.iml
*.apk
*.aar
*.zip
google-services.json
.project
.settings
.classpath
.vscode
================================================
FILE: .google/packaging.yaml
================================================
# GOOGLE SAMPLE PACKAGING DATA
#
# This file is used by Google as part of our samples packaging process.
# End users may safely ignore this file. It has no relevance to other systems.
---
status: PUBLISHED
technologies: [Android, Firebase]
categories: [Getting Started]
languages: [Java]
solutions: [Mobile, Monetization, Startup, Enterprise]
github: firebase/quickstart-android
branch: master
level: BEGINNER
icon: .google/icon.png
license: apache2
================================================
FILE: .opensource/project.json
================================================
{
"name": "Firebase Quickstarts for Android",
"parent": "quickstarts",
"type": "sample",
"platforms": [
"Android"
],
"content": "README.md",
"pages" : {
"admob/README.md": "Admob",
"analytics/README.md": "Analytics",
"appdistribution/README.md": "App Distribution",
"app-indexing/README.md": "App Indexing",
"auth/README.md": "Authentication",
"config/README.md": "Remote Config",
"crash/README.md": "Crashlytics",
"database/README.md": "Realtime Database",
"dynamiclinks/README.md": "Dynamic Links",
"firestore/README.md": "Firestore",
"functions/README.md": "Cloud Functions",
"inappmessaging/README.md": "In App Messaging",
"messaging/README.md": "Cloud Messaging",
"mlkit/README.md": "ML Kit",
"perf/README.md": "Performance Monitoring",
"storage/README.md": "Cloud Storage"
},
"related": [
"firebase/quickstart-ios",
"firebase/quickstart-js"
],
"tags": []
}
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to the Firebase Android Quickstarts
We'd love for you to contribute to our source code and to make the Firebase Android Quickstarts even better than it is today! Here are the guidelines we'd like you to follow:
- [Code of Conduct](#coc)
- [Question or Problem?](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submit)
- [Coding Rules](#rules)
- [Signing the CLA](#cla)
## <a name="coc"></a> Code of Conduct
As contributors and maintainers of the Firebase Android Quickstarts project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities.
Communication through any of Firebase's channels (GitHub, StackOverflow, Google+, Twitter, etc.) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to the project to do the same.
If any member of the community violates this code of conduct, the maintainers of the Firebase Android Quickstarts project may take action, removing issues, comments, and PRs or blocking accounts as deemed appropriate.
If you are subject to or witness unacceptable behavior, or have any other concerns, please drop us a line at nivco@google.com.
## <a name="question"></a> Got a Question or Problem?
If you have questions about how to use the Firebase Android Quickstarts, please direct these to [StackOverflow][stackoverflow] and use the `firebase` tag. We are also available on GitHub issues.
If you feel that we're missing an important bit of documentation, feel free to
file an issue so we can help. Here's an example to get you started:
```
What are you trying to do or find out more about?
Where have you looked?
Where did you expect to find this information?
```
## <a name="issue"></a> Found an Issue?
If you find a bug in the source code or a mistake in the documentation, you can help us by
submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
with a fix.
See [below](#submit) for some guidelines.
## <a name="submit"></a> Submission Guidelines
### Submitting an Issue
Before you submit your issue search the archive, maybe your question was already answered.
If your issue appears to be a bug, and hasn't been reported, open a new issue. Please fill out
all information in the issue template to maximize the chance that we can help you.
**If you get help, help others. Good karma rulez!**
### Submitting a Pull Request
Before you submit your pull request consider the following guidelines:
* Search [GitHub](https://github.com/firebase/firebase-quickstart-web/pulls) for an open or closed Pull Request
that relates to your submission. You don't want to duplicate effort.
* Please sign our [Contributor License Agreement (CLA)](#cla) before sending pull
requests. We cannot accept code without this.
* Make your changes in a new git branch:
```shell
$ git checkout -b my-fix-branch master
```
* Create your patch, **including appropriate test cases**.
* Follow our [Coding Rules](#rules).
* Avoid checking in files that shouldn't be tracked (e.g `*.class`, `.idea`, `.tmp`). We recommend using a [global](#global-gitignore) gitignore for this.
* Commit your changes using a descriptive commit message.
```shell
$ git commit -a
```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
* Build your changes locally to ensure all the tests pass:
```shell
$ ./gradlew build
```
* Push your branch to GitHub:
```shell
$ git push origin my-fix-branch
```
* In GitHub, send a pull request to `firebase-quickstart-android:master`.
* If we suggest changes then:
* Make the required updates.
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
```shell
$ git rebase master -i
$ git push origin my-fix-branch -f
```
That's it! Thank you for your contribution!
#### After your pull request is merged
After your pull request is merged, you can safely delete your branch and pull the changes
from the main (upstream) repository:
* Delete the remote branch on GitHub either through the GitHub Android UI or your local shell as follows:
```shell
$ git push origin --delete my-fix-branch
```
* Check out the master branch:
```shell
$ git checkout master -f
```
* Delete the local branch:
```shell
$ git branch -D my-fix-branch
```
* Update your master with the latest upstream version:
```shell
$ git pull --ff upstream master
```
## <a name="rules"></a> Coding Rules
Try to follow the same code style you see in the repository.
## <a name="cla"></a> Signing the CLA
Please sign our [Contributor License Agreement][google-cla] (CLA) before sending pull requests. For any code
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
*This guide was inspired by the [AngularJS contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).*
[github]: https://github.com/firebase/quickstart-android
[google-cla]: https://cla.developers.google.com
[stackoverflow]: http://stackoverflow.com/questions/tagged/firebase
[global-gitignore]: https://help.github.com/articles/ignoring-files/#create-a-global-gitignore
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 Google Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
All code in any directories or sub-directories that end with *.html or
*.css is licensed under the Creative Commons Attribution International
4.0 License, which full text can be found here:
https://creativecommons.org/licenses/by/4.0/legalcode.
As an exception to this license, all html or css that is generated by
the software at the direction of the user is copyright the user. The
user has full ownership and control over such content, including
whether and how they wish to license it.
================================================
FILE: README.md
================================================
# Firebase Quickstarts for Android
A collection of quickstart samples demonstrating the Firebase APIs on Android. For more information, see https://firebase.google.com.
## Samples
You can open each of the following samples as an Android Studio project, and run
them on a mobile device or a virtual device (AVD). When doing so you need to
add each sample app you wish to try to a Firebase project on the [Firebase
console](https://console.firebase.google.com). You can add multiple sample apps
to the same Firebase project. There's no need to create separate projects for
each app.
To add a sample app to a Firebase project, use the `applicationId` value specified
in the `app/build.gradle` file of the app as the Android package name. Download
the generated `google-services.json` file, and copy it to the `app/` directory of
the sample you wish to run.
- [Admob](admob/README.md)
- [Firebase AI Logic](firebase-ai/README.md)
- [Analytics](analytics/README.md)
- [App Distribution](appdistribution/README.md)
- [Auth](auth/README.md)
- [Remote Config](config/README.md)
- [Crashlytics](crash/README.md)
- [Realtime Database](database/README.md)
- [Data Connect](dataconnect/README.md)
- [Firestore](firestore/README.md)
- [Cloud Functions for Firebase](functions/README.md)
- [In-App Messaging](inappmessaging/README.md)
- [Cloud Messaging](messaging/README.md)
- [Performance Monitoring](perf/README.md)
- [Cloud Storage for Firebase](storage/README.md)
## How to make contributions?
Please read and follow the steps in the [CONTRIBUTING.md](CONTRIBUTING.md)
[![Actions Status][gh-actions-badge]][gh-actions]
[![SAM Score][sam-score-badge]][sam-score]
[gh-actions]: https://github.com/firebase/quickstart-android/actions
[gh-actions-badge]: https://github.com/firebase/quickstart-android/actions/workflows/android.yml/badge.svg?branch=master&event=push
[sam-score]: https://ossbot.computer/samscore.html
[sam-score-badge]: https://ossbot.computer/samscorebadge?org=firebase&repo=quickstart-android
================================================
FILE: admob/.gitignore
================================================
.gradle
/local.properties
.DS_Store
build/
google-services.json
# Android Studio
.idea
*.iml
================================================
FILE: admob/.google/packaging.yaml
================================================
# GOOGLE SAMPLE PACKAGING DATA
#
# This file is used by Google as part of our samples packaging process.
# End users may safely ignore this file. It has no relevance to other systems.
---
# Values: {DRAFT | PUBLISHED | INTERNAL | DEPRECATED | SUPERCEDED}
status: DRAFT
# Optional, put additional explanation here for DEPRECATED or SUPERCEDED.
# statusNote:
# See http://go/sample-categories
technologies: [Android, Google Play Services, Google AdMob]
categories: [Getting Started]
languages: [Java]
solutions: [Mobile]
# May be omitted if unpublished
# github: google/actionbar-basics
# Values: BEGINNER | INTERMEDIATE | ADVANCED | EXPERT
level: BEGINNER
# Dimensions: 512x512, PNG fomrat
icon: app/src/main/res/drawable/ic_launcher_big.png
# List of APIs that this sample should be listed under. Use authoritive,
# names that are unique for the product in question. Examples:
#
# Android - android:<class-name>
# App Engine - gae-java:<class name>
# gae-python:<package>
# Web Services - ws:<name of API from Cloud Console>
apiRefs:
- android:com.google.android.gms.ads
# Default: apache2. May be omitted for most samples.
# Alternatives: apache2-android (for AOSP)
license: apache2
================================================
FILE: admob/README.md
================================================
AdMob by Google Quickstart
=======================
The AdMob by Google Android quickstart demonstrates how to display an interstitial ad and
a banner ad. AdRequest and AdView are used to display a banner ad
and InterstitialAd is used to display the interstitial ad.
Introduction
------------
- [Read more about AdMob by Google](https://firebase.google.com/docs/admob/)
Getting Started
---------------
- [Add Firebase to your Android Project](https://firebase.google.com/docs/android/setup).
- Configure your AdMob app id:
- In `src/main/res/values/strings.xml` change the `admob_app_id` string to your AdMob app id.
- Note that this ID is used in two places: `AndroidManifest.xml` and `MainActivity`
- Run the sample on your Android device or emulator.
- The running sample displays a test banner ad and a test interstitial ad.
Result
-----------
<img src="app/src/screen.png" height="534" width="300"/>
Support
-------
- [Stack Overflow](https://stackoverflow.com/questions/tagged/admob)
- [Developer Forum](https://groups.google.com/group/google-admob-ads-sdk)
- [Firebase Support](https://firebase.google.com/support/)
License
-------
Copyright 2016 Google, Inc.
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
additional information regarding copyright ownership. The ASF licenses this
file to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
================================================
FILE: admob/app/build.gradle.kts
================================================
import com.android.build.gradle.internal.tasks.factory.dependsOn
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.google.services)
}
tasks {
check.dependsOn("assembleDebugAndroidTest")
}
android {
namespace = "com.google.samples.quickstart.admobexample"
compileSdk = 36
defaultConfig {
applicationId = "com.google.samples.quickstart.admobexample"
minSdk = 23
targetSdk = 36
versionCode = 1
versionName = "1.0"
multiDexEnabled = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
packaging {
resources.excludes += "LICENSE.txt"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
buildFeatures {
viewBinding = true
}
}
dependencies {
implementation(project(":internal:lintchecks"))
implementation(project(":internal:chooserx"))
implementation("androidx.appcompat:appcompat:1.7.1")
implementation("com.google.android.material:material:1.13.0")
implementation("androidx.browser:browser:1.5.0")
implementation("androidx.navigation:navigation-fragment-ktx:2.9.6")
implementation("androidx.navigation:navigation-ui-ktx:2.9.6")
implementation("com.google.android.gms:play-services-ads:23.3.0")
// Import the Firebase BoM (see: https://firebase.google.com/docs/android/learn-more#bom)
implementation(platform("com.google.firebase:firebase-bom:34.7.0"))
// For an optimal experience using AdMob, add the Firebase SDK
// for Google Analytics. This is recommended, but not required.
implementation("com.google.firebase:firebase-analytics")
debugImplementation("androidx.fragment:fragment-testing:1.8.9")
androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0")
androidTestImplementation("androidx.test:rules:1.7.0")
androidTestImplementation("androidx.test:runner:1.7.0")
androidTestImplementation("androidx.test.ext:junit:1.3.0")
}
================================================
FILE: admob/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-keepattributes EnclosingMethod
-keepattributes InnerClasses
================================================
FILE: admob/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- [SNIPPET modify_app_permissions]
Include required permissions for Google Mobile Ads to run.
[START modify_app_permissions] -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- [END modify_app_permissions] -->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
<!-- workaround for https://github.com/firebase/firebase-cpp-sdk/issues/1545 -->
<property
android:name="android.adservices.AD_SERVICES_CONFIG"
android:resource="@xml/gma_ad_services_config"
tools:replace="android:resource" />
<!--
This metadata is required or your app will crash!
-->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="@string/admob_app_id" />
<activity
android:name=".EntryChoiceActivity"
android:label="@string/app_name"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".java.MainActivity" />
<activity android:name=".kotlin.MainActivity" />
<!-- [SNIPPET add_activity_config_changes]
Include the AdActivity configChanges and theme.
[START add_activity_config_changes] -->
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="@android:style/Theme.Translucent" />
<!-- [END add_activity_config_changes] -->
</application>
</manifest>
================================================
FILE: admob/app/src/main/java/com/google/samples/quickstart/admobexample/EntryChoiceActivity.kt
================================================
package com.google.samples.quickstart.admobexample
import android.content.Intent
import com.firebase.example.internal.BaseEntryChoiceActivity
import com.firebase.example.internal.Choice
class EntryChoiceActivity : BaseEntryChoiceActivity() {
override fun getChoices(): List<Choice> {
return listOf(
Choice(
"Java",
"Run the Firebase Admob quickstart written in Java.",
Intent(this, com.google.samples.quickstart.admobexample.java.MainActivity::class.java),
),
Choice(
"Kotlin",
"Run the Firebase Admob quickstart written in Kotlin.",
Intent(this, com.google.samples.quickstart.admobexample.kotlin.MainActivity::class.java),
),
)
}
}
================================================
FILE: admob/app/src/main/java/com/google/samples/quickstart/admobexample/java/FirstFragment.java
================================================
package com.google.samples.quickstart.admobexample.java;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import com.google.samples.quickstart.admobexample.R;
import com.google.samples.quickstart.admobexample.databinding.FragmentFirstBinding;
class FirstFragment extends Fragment {
private static final String TAG = "MainActivity";
private static final String TEST_APP_ID = "ca-app-pub-3940256099942544~3347511713";
private AdView mAdView;
private InterstitialAd mInterstitialAd;
private Button mLoadInterstitialButton;
private FragmentFirstBinding binding;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentFirstBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
checkIds();
// Initialize the Google Mobile Ads SDK
MobileAds.initialize(getContext());
mAdView = binding.adView;
requestNewInterstitial();
mLoadInterstitialButton = binding.loadInterstitialButton;
mLoadInterstitialButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mInterstitialAd != null) {
mInterstitialAd.show(getActivity());
} else {
beginSecondActivity();
}
}
});
// Disable button if an interstitial ad is not loaded yet.
mLoadInterstitialButton.setEnabled(mInterstitialAd != null);
}
/**
* Load a new interstitial ad asynchronously.
*/
private void requestNewInterstitial() {
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
// AdMob ad unit IDs are not currently stored inside the google-services.json file.
// Developers using AdMob can store them as custom values in a string resource file or
// simply use constants. Note that the ad units used here are configured to return only test
// ads, and should not be used outside this sample.
InterstitialAd.load(getContext(), getString(R.string.interstitial_ad_unit_id), adRequest, new InterstitialAdLoadCallback() {
@Override
public void onAdLoaded(@NonNull InterstitialAd interstitialAd) {
super.onAdLoaded(interstitialAd);
mInterstitialAd = interstitialAd;
// Ad received, ready to display
if (mLoadInterstitialButton != null) {
mLoadInterstitialButton.setEnabled(true);
}
mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
@Override
public void onAdDismissedFullScreenContent() {
super.onAdDismissedFullScreenContent();
requestNewInterstitial();
beginSecondActivity();
}
});
}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
super.onAdFailedToLoad(loadAdError);
mInterstitialAd = null;
Log.w(TAG, "onAdFailedToLoad:" + loadAdError.getMessage());
}
});
}
private void beginSecondActivity() {
NavHostFragment.findNavController(this).navigate(R.id.action_FirstFragment_to_SecondFragment);
}
/** Called when leaving the activity */
@Override
public void onPause() {
if (mAdView != null) {
mAdView.pause();
}
super.onPause();
}
/** Called when returning to the activity */
@Override
public void onResume() {
super.onResume();
if (mAdView != null) {
mAdView.resume();
}
if (mInterstitialAd == null) {
requestNewInterstitial();
}
}
/** Called before the activity is destroyed */
@Override
public void onDestroy() {
if (mAdView != null) {
mAdView.destroy();
}
super.onDestroy();
}
@VisibleForTesting
public AdView getAdView() {
return mAdView;
}
private void checkIds() {
if (TEST_APP_ID.equals(getString(R.string.admob_app_id))) {
Log.w(TAG, "Your admob_app_id is not configured correctly, please see the README");
}
}
}
================================================
FILE: admob/app/src/main/java/com/google/samples/quickstart/admobexample/java/MainActivity.java
================================================
/**
* Copyright Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.samples.quickstart.admobexample.java;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.Navigation;
import com.google.samples.quickstart.admobexample.R;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Navigation.findNavController(this, R.id.nav_host_fragment).setGraph(R.navigation.nav_graph_java);
}
}
================================================
FILE: admob/app/src/main/java/com/google/samples/quickstart/admobexample/java/SecondFragment.java
================================================
package com.google.samples.quickstart.admobexample.java;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import com.google.samples.quickstart.admobexample.R;
class SecondFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_second, container, false);
}
}
================================================
FILE: admob/app/src/main/java/com/google/samples/quickstart/admobexample/kotlin/FirstFragment.kt
================================================
package com.google.samples.quickstart.admobexample.kotlin
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import com.google.samples.quickstart.admobexample.R
import com.google.samples.quickstart.admobexample.databinding.FragmentFirstBinding
class FirstFragment : Fragment() {
private var _binding: FragmentFirstBinding? = null
private val binding get() = _binding!!
private var interstitialAd: InterstitialAd? = null
private lateinit var adView: AdView
private lateinit var loadInterstitialButton: Button
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = FragmentFirstBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
adView = binding.adView
loadInterstitialButton = binding.loadInterstitialButton
checkIds()
// Initialize the Google Mobile Ads SDK
MobileAds.initialize(requireContext())
requestNewInterstitial()
loadInterstitialButton.setOnClickListener {
if (interstitialAd != null) {
interstitialAd?.show(requireActivity())
} else {
goToNextFragment()
}
}
// Disable button if an interstitial ad is not loaded yet.
loadInterstitialButton.isEnabled = interstitialAd != null
}
/**
* Load a new interstitial ad asynchronously.
*/
private fun requestNewInterstitial() {
// AdMob ad unit IDs are not currently stored inside the google-services.json file.
// Developers using AdMob can store them as custom values in a string resource file or
// simply use constants. Note that the ad units used here are configured to return only test
// ads, and should not be used outside this sample.
val adRequest = AdRequest.Builder().build()
adView.loadAd(adRequest)
InterstitialAd.load(
requireContext(),
getString(R.string.interstitial_ad_unit_id),
adRequest,
object : InterstitialAdLoadCallback() {
override fun onAdLoaded(ad: InterstitialAd) {
super.onAdLoaded(ad)
interstitialAd = ad
// Ad received, ready to display
loadInterstitialButton.isEnabled = true
interstitialAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdDismissedFullScreenContent() {
super.onAdDismissedFullScreenContent()
goToNextFragment()
}
}
}
override fun onAdFailedToLoad(error: LoadAdError) {
super.onAdFailedToLoad(error)
interstitialAd = null
Log.w(TAG, "onAdFailedToLoad:${error.message}")
}
},
)
}
private fun goToNextFragment() {
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
}
/** Called when leaving the activity */
override fun onPause() {
adView.pause()
super.onPause()
}
/** Called when returning to the activity */
override fun onResume() {
super.onResume()
adView.resume()
if (interstitialAd == null) {
requestNewInterstitial()
}
}
/** Called before the activity is destroyed */
override fun onDestroy() {
adView.destroy()
super.onDestroy()
}
private fun checkIds() {
if (TEST_APP_ID == getString(R.string.admob_app_id)) {
Log.w(TAG, "Your admob_app_id is not configured correctly, please see the README")
}
}
companion object {
private const val TAG = "FirstFragment"
private const val TEST_APP_ID = "ca-app-pub-3940256099942544~3347511713"
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
================================================
FILE: admob/app/src/main/java/com/google/samples/quickstart/admobexample/kotlin/MainActivity.kt
================================================
package com.google.samples.quickstart.admobexample.kotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import com.google.samples.quickstart.admobexample.R
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findNavController(R.id.nav_host_fragment).setGraph(R.navigation.nav_graph_kotlin)
}
}
================================================
FILE: admob/app/src/main/java/com/google/samples/quickstart/admobexample/kotlin/SecondFragment.kt
================================================
package com.google.samples.quickstart.admobexample.kotlin
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.google.samples.quickstart.admobexample.R
class SecondFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_second, container, false)
}
}
================================================
FILE: admob/app/src/main/res/layout/activity_main.xml
================================================
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:viewBindingIgnore="true">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
================================================
FILE: admob/app/src/main/res/layout/fragment_first.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:src="@drawable/firebase_lockup_400"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/loadInterstitialButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/interstitial_button_text"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline" />
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
ads:adSize="BANNER"
ads:adUnitId="@string/banner_ad_unit_id"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
================================================
FILE: admob/app/src/main/res/layout/fragment_second.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:viewBindingIgnore="true">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:src="@drawable/firebase_lockup_400"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/icon"
android:layout_gravity="center_horizontal"
android:text="@string/second_fragment_content"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="@+id/icon"
app:layout_constraintStart_toStartOf="@+id/icon"
app:layout_constraintTop_toBottomOf="@+id/icon" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
================================================
FILE: admob/app/src/main/res/navigation/nav_graph_java.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph_java"
app:startDestination="@id/FirstFragment">
<fragment
android:id="@+id/FirstFragment"
android:name="com.google.samples.quickstart.admobexample.java.FirstFragment"
android:label="@string/first_fragment_title"
tools:layout="@layout/fragment_first">
<action
android:id="@+id/action_FirstFragment_to_SecondFragment"
app:destination="@id/SecondFragment" />
</fragment>
<fragment
android:id="@+id/SecondFragment"
android:name="com.google.samples.quickstart.admobexample.java.SecondFragment"
android:label="@string/second_fragment_title"
tools:layout="@layout/fragment_second">
</fragment>
</navigation>
================================================
FILE: admob/app/src/main/res/navigation/nav_graph_kotlin.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph_kotlin"
app:startDestination="@id/FirstFragment">
<fragment
android:id="@+id/FirstFragment"
android:name="com.google.samples.quickstart.admobexample.kotlin.FirstFragment"
android:label="@string/first_fragment_title"
tools:layout="@layout/fragment_first">
<action
android:id="@+id/action_FirstFragment_to_SecondFragment"
app:destination="@id/SecondFragment" />
</fragment>
<fragment
android:id="@+id/SecondFragment"
android:name="com.google.samples.quickstart.admobexample.kotlin.SecondFragment"
android:label="@string/second_fragment_title"
tools:layout="@layout/fragment_second">
</fragment>
</navigation>
================================================
FILE: admob/app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#039BE5</color>
<color name="colorPrimaryDark">#0288D1</color>
<color name="colorAccent">#FFA000</color>
</resources>
================================================
FILE: admob/app/src/main/res/values/dimens.xml
================================================
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
================================================
FILE: admob/app/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">AdMob Quickstart</string>
<string name="hello_world">Hello world!</string>
<string name="interstitial_button_text">Show Interstitial Ad</string>
<string name="first_fragment_title">FirstFragment</string>
<string name="second_fragment_title">SecondFragment</string>
<string name="second_fragment_content">This is the second fragment.</string>
<!--
TODO: Replace this with your own Admob App ID! This value is only a sample.
-->
<string name="admob_app_id">ca-app-pub-3940256099942544~3347511713</string>
<string name="banner_ad_unit_id">ca-app-pub-3940256099942544/6300978111</string>
<string name="interstitial_ad_unit_id">ca-app-pub-3940256099942544/1033173712</string>
</resources>
================================================
FILE: admob/app/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
================================================
FILE: admob/app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
================================================
FILE: admob/build.gradle.kts
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.google.services) apply false
}
allprojects {
repositories {
mavenLocal()
google()
mavenCentral()
}
}
================================================
FILE: admob/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: admob/gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useAndroidX=true
================================================
FILE: admob/gradlew
================================================
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
================================================
FILE: admob/gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: admob/settings.gradle.kts
================================================
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
include(":app")
// Required so that gradle can resolve these dependencies even when
// building only a single project.
include(":internal:lintchecks")
project(":internal:lintchecks").projectDir = file("../internal/lintchecks")
include(":internal:lint")
project(":internal:lint").projectDir = file("../internal/lint")
include(":internal:chooserx")
project(":internal:chooserx").projectDir = file("../internal/chooserx")
================================================
FILE: analytics/.gitignore
================================================
.gradle
/local.properties
.DS_Store
build/
google-services.json
# Android Studio
.idea
*.iml
================================================
FILE: analytics/README.md
================================================
Google Analytics for Firebase Quickstart
========================================
Introduction
------------
- [Read more about Google Analytics for Firebase](https://firebase.google.com/docs/analytics)
Getting Started
---------------
- [Add Firebase to your Android Project](https://firebase.google.com/docs/android/setup).
- Run the sample on Android device or emulator.
Result
-----------
After running the app you should see a screen like this:
<img src="app/src/screen.png" height="534" width="300"/>
The first time you run the app you will be asked what your
favorite food is. This choice will be logged to Firebase
Analytics as a [User Property][user-props].
As you swipe between tabs in the app, `SELECT_CONTENT` events
are logged to Analytics. You can see these events in
real time using [Debug View][debug-view].
Support
-------
- [Stack Overflow](https://stackoverflow.com/questions/tagged/firebase-analytics)
- [Firebase Support](https://firebase.google.com/support/)
License
-------
Copyright 2016 Google, Inc.
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
additional information regarding copyright ownership. The ASF licenses this
file to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
[user-props]: https://firebase.google.com/docs/analytics/android/properties
[debug-view]: https://firebase.google.com/docs/analytics/debugview
================================================
FILE: analytics/app/build.gradle.kts
================================================
import com.android.build.gradle.internal.tasks.factory.dependsOn
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.google.services)
}
tasks {
check.dependsOn("assembleDebugAndroidTest")
}
android {
namespace = "com.google.firebase.quickstart.analytics"
compileSdk = 36
defaultConfig {
applicationId = "com.google.firebase.quickstart.analytics"
minSdk = 23
targetSdk = 36
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled = true
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
buildFeatures {
viewBinding = true
}
}
dependencies {
implementation(project(":internal:lintchecks"))
implementation(project(":internal:chooserx"))
implementation("com.google.android.material:material:1.13.0")
implementation("androidx.appcompat:appcompat:1.7.1")
implementation("androidx.preference:preference-ktx:1.2.1")
// Needed to override the version used by preference-ktx
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0")
// Import the Firebase BoM (see: https://firebase.google.com/docs/android/learn-more#bom)
implementation(platform("com.google.firebase:firebase-bom:34.7.0"))
// Firebase Analytics
implementation("com.google.firebase:firebase-analytics")
androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0")
androidTestImplementation("androidx.test:rules:1.7.0")
androidTestImplementation("androidx.test:runner:1.7.0")
androidTestImplementation("androidx.test.ext:junit:1.3.0")
}
================================================
FILE: analytics/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-keepattributes EnclosingMethod
-keepattributes InnerClasses
================================================
FILE: analytics/app/src/androidTest/java/com/google/firebase/quickstart/analytics/MainActivityTest.java
================================================
package com.google.firebase.quickstart.analytics;
import androidx.annotation.StringRes;
import androidx.test.espresso.NoMatchingViewException;
import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.rule.ActivityTestRule;
import androidx.test.filters.LargeTest;
import com.google.firebase.quickstart.analytics.java.MainActivity;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.swipeLeft;
import static androidx.test.espresso.action.ViewActions.swipeRight;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withParent;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void mainActivityTest() {
// Select favorite food if the dialog appears
selectFavoriteFoodIfPossible("Hot Dogs");
// Initial title
checkTitleText(R.string.pattern1_title);
// Swipe, make sure we see the right titles
ViewInteraction viewPager = onView(withId(R.id.viewPager));
viewPager.check(matches(isDisplayed()));
// Swipe left
viewPager.perform(swipeLeft());
checkTitleText(R.string.pattern2_title);
// Swipe left
viewPager.perform(swipeLeft());
checkTitleText(R.string.pattern3_title);
// Swipe back right
viewPager.perform(swipeRight());
checkTitleText(R.string.pattern2_title);
}
private void checkTitleText(@StringRes int resId) {
onView(withText(resId))
.check(matches(isDisplayed()));
}
private void selectFavoriteFoodIfPossible(String food) {
try{
ViewInteraction appCompatTextView = onView(
allOf(withId(android.R.id.text1), withText(food),
withParent(allOf(withId(R.id.select_dialog_listview),
withParent(withId(R.id.contentPanel)))),
isDisplayed()));
appCompatTextView.perform(click());
} catch (NoMatchingViewException e) {
// This is ok
}
}
}
================================================
FILE: analytics/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="com.google.firebase.quickstart.analytics.java.MainActivity"/>
<activity
android:name="com.google.firebase.quickstart.analytics.kotlin.MainActivity"/>
<activity
android:name="com.google.firebase.quickstart.analytics.EntryChoiceActivity"
android:label="@string/app_name"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: analytics/app/src/main/java/com/google/firebase/quickstart/analytics/EntryChoiceActivity.kt
================================================
package com.google.firebase.quickstart.analytics
import android.content.Intent
import com.firebase.example.internal.BaseEntryChoiceActivity
import com.firebase.example.internal.Choice
class EntryChoiceActivity : BaseEntryChoiceActivity() {
override fun getChoices(): List<Choice> {
return listOf(
Choice(
"Java",
"Run the Firebase Analytics quickstart written in Java.",
Intent(
this,
com.google.firebase.quickstart.analytics.java.MainActivity::class.java,
),
),
Choice(
"Kotlin",
"Run the Firebase Analytics quickstart written in Kotlin.",
Intent(
this,
com.google.firebase.quickstart.analytics.kotlin.MainActivity::class.java,
),
),
)
}
}
================================================
FILE: analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/ImageFragment.java
================================================
/*
* Copyright Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.firebase.quickstart.analytics.java;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.fragment.app.Fragment;
import com.google.firebase.quickstart.analytics.R;
/**
* This fragment displays a featured, specified image.
*/
public class ImageFragment extends Fragment {
private static final String ARG_PATTERN = "pattern";
private int resId;
/**
* Create a {@link ImageFragment} displaying the given image.
*
* @param resId to display as the featured image
* @return a new instance of {@link ImageFragment}
*/
public static ImageFragment newInstance(int resId) {
ImageFragment fragment = new ImageFragment();
Bundle args = new Bundle();
args.putInt(ARG_PATTERN, resId);
fragment.setArguments(args);
return fragment;
}
public ImageFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
resId = getArguments().getInt(ARG_PATTERN);
}
}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, null);
ImageView imageView = view.findViewById(R.id.imageView);
imageView.setImageResource(resId);
return view;
}
}
================================================
FILE: analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/ImageInfo.java
================================================
/*
* Copyright Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.firebase.quickstart.analytics.java;
/**
* Pair of resource IDs representing an image and its title.
*/
public class ImageInfo {
public final int image;
public final int title;
public final int id;
/**
* Create a new ImageInfo.
*
* @param image resource of image
* @param title resource of title
* @param id resource of id
*/
public ImageInfo(int image, int title, int id) {
this.image = image;
this.title = title;
this.id = id;
}
}
================================================
FILE: analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/MainActivity.java
================================================
/*
* Copyright Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* For more information on setting up and running this sample code, see
* https://firebase.google.com/docs/analytics/android
*/
package com.google.firebase.quickstart.analytics.java;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.preference.PreferenceManager;
import androidx.viewpager.widget.ViewPager;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.firebase.quickstart.analytics.R;
import com.google.firebase.quickstart.analytics.databinding.ActivityMainBinding;
import java.util.Locale;
/**
* Activity which displays numerous background images that may be viewed. These background images
* are shown via {@link ImageFragment}.
*/
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final String KEY_FAVORITE_FOOD = "favorite_food";
private static final ImageInfo[] IMAGE_INFOS = {
new ImageInfo(R.drawable.favorite, R.string.pattern1_title, R.string.pattern1_id),
new ImageInfo(R.drawable.flash, R.string.pattern2_title, R.string.pattern2_id),
new ImageInfo(R.drawable.face, R.string.pattern3_title, R.string.pattern3_id),
new ImageInfo(R.drawable.whitebalance, R.string.pattern4_title, R.string.pattern4_id),
};
private ActivityMainBinding binding;
/**
* The {@link androidx.viewpager.widget.PagerAdapter} that will provide fragments for each image.
* This uses a {@link FragmentStateAdapter}, which keeps every loaded fragment in memory.
*/
private ImagePagerAdapter mImagePagerAdapter;
/**
* The {@link ViewPager} that will host the patterns.
*/
private ViewPager2 mViewPager;
/**
* The {@code FirebaseAnalytics} used to record screen views.
*/
// [START declare_analytics]
private FirebaseAnalytics mFirebaseAnalytics;
// [END declare_analytics]
/**
* The user's favorite food, chosen from a dialog.
*/
private String mFavoriteFood;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// [START shared_app_measurement]
// Obtain the FirebaseAnalytics instance.
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
// [END shared_app_measurement]
// On first app open, ask the user his/her favorite food. Then set this as a user property
// on all subsequent opens.
String userFavoriteFood = getUserFavoriteFood();
if (userFavoriteFood == null) {
askFavoriteFood();
} else {
setUserFavoriteFood(userFavoriteFood);
}
// Create the adapter that will return a fragment for each image.
mImagePagerAdapter = new ImagePagerAdapter(getSupportFragmentManager(), IMAGE_INFOS, getLifecycle());
// Set up the ViewPager with the pattern adapter.
mViewPager = binding.viewPager;
mViewPager.setAdapter(mImagePagerAdapter);
mViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
recordImageView();
recordScreenView();
}
});
TabLayout tabLayout = binding.tabLayout;
// When the visible image changes, send a screen view hit.
new TabLayoutMediator(tabLayout, mViewPager, new TabLayoutMediator.TabConfigurationStrategy() {
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText(IMAGE_INFOS[position].title);
}
}).attach();
// Send initial screen screen view hit.
recordImageView();
}
@Override
public void onResume() {
super.onResume();
recordScreenView();
}
/**
* Display a dialog prompting the user to pick a favorite food from a list, then record
* the answer.
*/
private void askFavoriteFood() {
final String[] choices = getResources().getStringArray(R.array.food_items);
AlertDialog ad = new AlertDialog.Builder(this)
.setCancelable(false)
.setTitle(R.string.food_dialog_title)
.setItems(choices, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String food = choices[which];
setUserFavoriteFood(food);
}
}).create();
ad.show();
}
/**
* Get the user's favorite food from shared preferences.
* @return favorite food, as a string.
*/
private String getUserFavoriteFood() {
return PreferenceManager.getDefaultSharedPreferences(this)
.getString(KEY_FAVORITE_FOOD, null);
}
/**
* Set the user's favorite food as an app measurement user property and in shared preferences.
* @param food the user's favorite food.
*/
private void setUserFavoriteFood(String food) {
Log.d(TAG, "setFavoriteFood: " + food);
mFavoriteFood = food;
PreferenceManager.getDefaultSharedPreferences(this).edit()
.putString(KEY_FAVORITE_FOOD, food)
.apply();
// [START user_property]
mFirebaseAnalytics.setUserProperty("favorite_food", mFavoriteFood);
// [END user_property]
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int i = item.getItemId();
if (i == R.id.menu_share) {
String name = getCurrentImageTitle();
String text = "I'd love you to hear about " + name;
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, text);
sendIntent.setType("text/plain");
startActivity(sendIntent);
// [START custom_event]
Bundle params = new Bundle();
params.putString("image_name", name);
params.putString("full_text", text);
mFirebaseAnalytics.logEvent("share_image", params);
// [END custom_event]
}
return false;
}
/**
* Return the title of the currently displayed image.
*
* @return title of image
*/
private String getCurrentImageTitle() {
int position = mViewPager.getCurrentItem();
ImageInfo info = IMAGE_INFOS[position];
return getString(info.title);
}
/**
* Return the id of the currently displayed image.
*
* @return id of image
*/
private String getCurrentImageId() {
int position = mViewPager.getCurrentItem();
ImageInfo info = IMAGE_INFOS[position];
return getString(info.id);
}
/**
* Record a screen view for the visible {@link ImageFragment} displayed
* inside {@link FragmentStateAdapter}.
*/
private void recordImageView() {
String id = getCurrentImageId();
String name = getCurrentImageTitle();
// [START image_view_event]
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.ITEM_ID, id);
bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, name);
bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "image");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle);
// [END image_view_event]
}
/**
* This sample has a single Activity, so we need to manually record "screen views" as
* we change fragments.
*/
private void recordScreenView() {
// This string must be <= 36 characters long.
String screenName = getCurrentImageId() + "-" + getCurrentImageTitle();
// [START set_current_screen]
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.SCREEN_NAME, screenName);
bundle.putString(FirebaseAnalytics.Param.SCREEN_CLASS, "MainActivity");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle);
// [END set_current_screen]
}
/**
* A {@link FragmentStateAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class ImagePagerAdapter extends FragmentStateAdapter {
private final ImageInfo[] infos;
public ImagePagerAdapter(FragmentManager fm, ImageInfo[] infos, Lifecycle lifecyle) {
super(fm, lifecyle);
this.infos = infos;
}
public CharSequence getPageTitle(int position) {
if (position < 0 || position >= infos.length) {
return null;
}
Locale l = Locale.getDefault();
ImageInfo info = infos[position];
return getString(info.title).toUpperCase(l);
}
@NonNull
@Override
public Fragment createFragment(int position) {
ImageInfo info = infos[position];
return ImageFragment.newInstance(info.image);
}
@Override
public int getItemCount() {
return infos.length;
}
}
}
================================================
FILE: analytics/app/src/main/java/com/google/firebase/quickstart/analytics/kotlin/ImageFragment.kt
================================================
package com.google.firebase.quickstart.analytics.kotlin
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.fragment.app.Fragment
import com.google.firebase.quickstart.analytics.R
/**
* This fragment displays a featured, specified image.
*/
class ImageFragment : Fragment() {
private var resId: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
resId = it.getInt(ARG_PATTERN)
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view = inflater.inflate(R.layout.fragment_main, null)
val imageView = view.findViewById<ImageView>(R.id.imageView)
imageView.setImageResource(resId)
return view
}
companion object {
private const val ARG_PATTERN = "pattern"
/**
* Create a [ImageFragment] displaying the given image.
*
* @param resId to display as the featured image
* @return a new instance of [ImageFragment]
*/
fun newInstance(resId: Int): ImageFragment {
val fragment = ImageFragment()
val args = Bundle()
args.putInt(ARG_PATTERN, resId)
fragment.arguments = args
return fragment
}
}
}
================================================
FILE: analytics/app/src/main/java/com/google/firebase/quickstart/analytics/kotlin/ImageInfo.kt
================================================
package com.google.firebase.quickstart.analytics.kotlin
/**
* Pair of resource IDs representing an image and its title.
*/
data class ImageInfo(val image: Int, val title: Int, val id: Int)
================================================
FILE: analytics/app/src/main/java/com/google/firebase/quickstart/analytics/kotlin/MainActivity.kt
================================================
package com.google.firebase.quickstart.analytics.kotlin
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import com.google.firebase.Firebase
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.analytics
import com.google.firebase.analytics.logEvent
import com.google.firebase.quickstart.analytics.R
import com.google.firebase.quickstart.analytics.databinding.ActivityMainBinding
import com.google.firebase.quickstart.analytics.kotlin.MainActivity.Companion.IMAGE_INFOS
import java.util.Locale
/**
* Activity which displays numerous background images that may be viewed. These background images
* are shown via {@link ImageFragment}.
*/
class MainActivity : AppCompatActivity() {
companion object {
private const val TAG = "MainActivity"
private const val KEY_FAVORITE_FOOD = "favorite_food"
private val IMAGE_INFOS = arrayOf(
ImageInfo(R.drawable.favorite, R.string.pattern1_title, R.string.pattern1_id),
ImageInfo(R.drawable.flash, R.string.pattern2_title, R.string.pattern2_id),
ImageInfo(R.drawable.face, R.string.pattern3_title, R.string.pattern3_id),
ImageInfo(R.drawable.whitebalance, R.string.pattern4_title, R.string.pattern4_id),
)
}
private lateinit var binding: ActivityMainBinding
/**
* The [androidx.viewpager2.widget.PagerAdapter] that will provide fragments for each image.
* This uses a [FragmentStateAdapter], which keeps every loaded fragment in memory.
*/
private lateinit var imagePagerAdapter: ImagePagerAdapter
/**
* The `FirebaseAnalytics` used to record screen views.
*/
// [START declare_analytics]
private lateinit var firebaseAnalytics: FirebaseAnalytics
// [END declare_analytics]
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// [START shared_app_measurement]
// Obtain the FirebaseAnalytics instance.
firebaseAnalytics = Firebase.analytics
// [END shared_app_measurement]
// On first app open, ask the user his/her favorite food. Then set this as a user property
// on all subsequent opens.
val userFavoriteFood = getUserFavoriteFood()
if (userFavoriteFood == null) {
askFavoriteFood()
} else {
setUserFavoriteFood(userFavoriteFood)
}
// Create the adapter that will return a fragment for each image.
imagePagerAdapter = ImagePagerAdapter(supportFragmentManager, IMAGE_INFOS, lifecycle)
// Set up the ViewPager with the pattern adapter.
binding.viewPager.adapter = imagePagerAdapter
val pageChangedCallback = object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
recordImageView()
recordScreenView()
}
}
binding.viewPager.registerOnPageChangeCallback(pageChangedCallback)
val tabLayout: TabLayout = binding.tabLayout
TabLayoutMediator(tabLayout, binding.viewPager) { tab, position ->
tab.setText(IMAGE_INFOS[position].title)
}.attach()
// Send initial screen screen view hit.
recordImageView()
}
public override fun onResume() {
super.onResume()
recordScreenView()
}
/**
* Display a dialog prompting the user to pick a favorite food from a list, then record
* the answer.
*/
private fun askFavoriteFood() {
val choices = resources.getStringArray(R.array.food_items)
val ad = AlertDialog.Builder(this)
.setCancelable(false)
.setTitle(R.string.food_dialog_title)
.setItems(choices) { _, which ->
val food = choices[which]
setUserFavoriteFood(food)
}.create()
ad.show()
}
/**
* Get the user's favorite food from shared preferences.
* @return favorite food, as a string.
*/
private fun getUserFavoriteFood(): String? {
return PreferenceManager.getDefaultSharedPreferences(this)
.getString(KEY_FAVORITE_FOOD, null)
}
/**
* Set the user's favorite food as an app measurement user property and in shared preferences.
* @param food the user's favorite food.
*/
private fun setUserFavoriteFood(food: String) {
Log.d(TAG, "setFavoriteFood: $food")
PreferenceManager.getDefaultSharedPreferences(this).edit()
.putString(KEY_FAVORITE_FOOD, food)
.apply()
// [START user_property]
firebaseAnalytics.setUserProperty("favorite_food", food)
// [END user_property]
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val i = item.itemId
if (i == R.id.menu_share) {
val name = getCurrentImageTitle()
val text = "I'd love you to hear about $name"
val sendIntent = Intent()
sendIntent.action = Intent.ACTION_SEND
sendIntent.putExtra(Intent.EXTRA_TEXT, text)
sendIntent.type = "text/plain"
startActivity(sendIntent)
// [START custom_event]
firebaseAnalytics.logEvent("share_image") {
param("image_name", name)
param("full_text", text)
}
// [END custom_event]
}
return false
}
/**
* Return the title of the currently displayed image.
*
* @return title of image
*/
private fun getCurrentImageTitle(): String {
val position = binding.viewPager.currentItem
val info = IMAGE_INFOS[position]
return getString(info.title)
}
/**
* Return the id of the currently displayed image.
*
* @return id of image
*/
private fun getCurrentImageId(): String {
val position = binding.viewPager.currentItem
val info = IMAGE_INFOS[position]
return getString(info.id)
}
/**
* Record a screen view for the visible [ImageFragment] displayed
* inside [FragmentStateAdapter].
*/
private fun recordImageView() {
val id = getCurrentImageId()
val name = getCurrentImageTitle()
// [START image_view_event]
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_ITEM) {
param(FirebaseAnalytics.Param.ITEM_ID, id)
param(FirebaseAnalytics.Param.ITEM_NAME, name)
param(FirebaseAnalytics.Param.CONTENT_TYPE, "image")
}
// [END image_view_event]
}
/**
* This sample has a single Activity, so we need to manually record "screen views" as
* we change fragments.
*/
private fun recordScreenView() {
// This string must be <= 36 characters long.
val screenName = "${getCurrentImageId()}-${getCurrentImageTitle()}"
// [START set_current_screen]
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) {
param(FirebaseAnalytics.Param.SCREEN_NAME, screenName)
param(FirebaseAnalytics.Param.SCREEN_CLASS, "MainActivity")
}
// [END set_current_screen]
}
/**
* A [FragmentStateAdapter] that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
inner class ImagePagerAdapter(
fm: FragmentManager,
private val infos: Array<ImageInfo>,
lifecyle: Lifecycle,
) : FragmentStateAdapter(fm, lifecyle) {
fun getPageTitle(position: Int): CharSequence? {
if (position < 0 || position >= infos.size) {
return null
}
val l = Locale.getDefault()
val info = infos[position]
return getString(info.title).uppercase(l)
}
override fun getItemCount(): Int = infos.size
override fun createFragment(position: Int): Fragment {
val info = infos[position]
return ImageFragment.newInstance(info.image)
}
}
}
================================================
FILE: analytics/app/src/main/res/drawable/circle.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#fff" />
</shape>
================================================
FILE: analytics/app/src/main/res/layout/activity_main.xml
================================================
<!--
Copyright 2015 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tab_layout" />
</androidx.constraintlayout.widget.ConstraintLayout>
================================================
FILE: analytics/app/src/main/res/layout/fragment_main.xml
================================================
<!--
Copyright 2015 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:viewBindingIgnore="true"
tools:context="com.google.firebase.quickstart.analytics.java.ImageFragment">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:minHeight="256dp"
android:minWidth="256dp"
android:layout_gravity="center"
android:elevation="2dp"
android:scaleType="center"
android:background="@drawable/circle"/>
</FrameLayout>
================================================
FILE: analytics/app/src/main/res/menu/main.xml
================================================
<!--
Copyright 2015 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_share" android:title="@string/menu_share" app:showAsAction="never" />
</menu>
================================================
FILE: analytics/app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#039BE5</color>
<color name="colorPrimaryDark">#0288D1</color>
<color name="colorAccent">#FFA000</color>
</resources>
================================================
FILE: analytics/app/src/main/res/values/dimens.xml
================================================
<!--
Copyright 2015 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
-->
<resources>
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
================================================
FILE: analytics/app/src/main/res/values/strings.xml
================================================
<!--
Copyright 2015 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
-->
<resources>
<string name="app_name">Firebase Analytics</string>
<string name="pattern1_title">A</string>
<string name="pattern2_title">B</string>
<string name="pattern3_title">C</string>
<string name="pattern4_title">D</string>
<string name="pattern1_id">id-A</string>
<string name="pattern2_id">id-B</string>
<string name="pattern3_id">id-C</string>
<string name="pattern4_id">id-D</string>
<string name="menu_share">Share</string>
<string name="food_dialog_title">Which food is your favorite?</string>
<array name="food_items">
<item>Hot Dogs</item>
<item>Hamburgers</item>
<item>Pizza</item>
</array>
</resources>
================================================
FILE: analytics/app/src/main/res/values/styles.xml
================================================
<!--
Copyright 2015 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
-->
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
</style>
</resources>
================================================
FILE: analytics/app/src/main/res/values-v21/styles.xml
================================================
<!--
Copyright 2015 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
-->
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="android:colorAccent">@color/colorAccent</item>
</style>
</resources>
================================================
FILE: analytics/app/src/main/res/values-w820dp/dimens.xml
================================================
<!--
Copyright 2015 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
-->
<resources>
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
================================================
FILE: analytics/build.gradle.kts
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.google.services) apply false
}
allprojects {
repositories {
//mavenLocal() must be listed at the top to facilitate testing
mavenLocal()
google()
mavenCentral()
}
}
================================================
FILE: analytics/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: analytics/gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useAndroidX=true
================================================
FILE: analytics/gradlew
================================================
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
================================================
FILE: analytics/gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: analytics/settings.gradle.kts
================================================
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
include(":app")
// Required so that gradle can resolve these dependencies even when
// building only a single project.
include(":internal:lintchecks")
project(":internal:lintchecks").projectDir = file("../internal/lintchecks")
include(":internal:lint")
project(":internal:lint").projectDir = file("../internal/lint")
include(":internal:chooserx")
project(":internal:chooserx").projectDir = file("../internal/chooserx")
================================================
FILE: appdistribution/.gitignore
================================================
.gradle
local.properties
.idea
build/
.DS_Store
*.iml
*.apk
*.aar
*.zip
google-services.json
================================================
FILE: appdistribution/README.md
================================================
# Firebase App Distribution Quickstart
## Introduction
The Firebase App Distribution SDK enables you to display in-app alerts to your testers when new builds of your app are available to install. This quickstart aims to showcase how to use the App Distribution SDK to create and customize new build alerts for your testers. You can read more
about Firebase App Distribution [here](https://firebase.google.com/docs/app-distribution)!
## Getting Started
* Follow the instructions to [add Firebase to your Android app][add-firebase-android].
## Result
<img src="docs/result.png" height="600" />
[add-firebase-android]: https://firebase.google.com/docs/android/setup
================================================
FILE: appdistribution/app/.gitignore
================================================
/build
================================================
FILE: appdistribution/app/build.gradle.kts
================================================
plugins {
id("com.android.application")
id("com.google.gms.google-services")
}
android {
namespace = "com.google.firebase.appdistributionquickstart"
compileSdk = 36
defaultConfig {
applicationId = "com.google.firebase.appdistributionquickstart"
minSdk = 23
targetSdk = 36
versionCode = 1
versionName = "1.0"
multiDexEnabled = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
buildFeatures {
viewBinding = true
}
lint {
warning.add("InvalidPackage")
// TODO(thatfiredev): Remove this once
// https://github.com/bumptech/glide/issues/4940 is fixed
// (and the same change gets applied to App Distribution)
disable.add("NotificationPermission")
}
}
dependencies {
implementation(project(":internal:lintchecks"))
implementation(project(":internal:chooserx"))
implementation("com.google.android.material:material:1.13.0")
implementation("androidx.constraintlayout:constraintlayout:2.2.1")
// Import the Firebase BoM (see: https://firebase.google.com/docs/android/learn-more#bom)
implementation(platform("com.google.firebase:firebase-bom:34.7.0"))
// ADD the SDK to the "prerelease" variant only (example)
implementation("com.google.firebase:firebase-appdistribution:16.0.0-beta17")
// For an optimal experience using App Distribution, add the Firebase SDK
// for Google Analytics. This is recommended, but not required.
implementation("com.google.firebase:firebase-analytics")
androidTestImplementation("androidx.test:runner:1.7.0")
androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0")
androidTestImplementation("androidx.test:rules:1.7.0")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
}
================================================
FILE: appdistribution/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: appdistribution/app/src/androidTest/java/com/google/firebase/appdistributionquickstart/InstrumentedTest.java
================================================
package com.google.firebase.appdistributionquickstart;
import android.os.RemoteException;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.test.espresso.Root;
import androidx.test.espresso.ViewInteraction;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.UiDevice;
import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import com.google.firebase.appdistributionquickstart.java.MainActivity;
/**
* Instrumented test, which will execute on an Android device.
*
*/
@RunWith(AndroidJUnit4.class)
public class InstrumentedTest {
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);
private Matcher<Root> rootMatcher;
@Before
public void setUp() {
rootMatcher = withDecorView(not(is(mActivityRule.getActivity().getWindow().getDecorView())));
}
@After
public void tearDown() {
getView(R.id.collapse_button).perform(click());
}
@Test
public void testFiamDisplaysOnForegroundCampaign() {
reopen_app(); // reopen app to correctly trigger fetch
getView(R.id.modal_root).check(matches(isDisplayed()));
}
@Test
public void testFiamDisplaysContextualTriggerCampaign() {
onView(withId(R.id.eventTriggerButton)).perform(click());
getView(R.id.modal_root).check(matches(isDisplayed()));
}
private void reopen_app() {
press_recent();
press_back();
}
private void press_recent() {
try {
UiDevice.getInstance(getInstrumentation()).pressRecentApps();
} catch (RemoteException e) {
e.printStackTrace();
}
sleep();
}
private void press_back() {
UiDevice.getInstance(getInstrumentation()).pressBack();
sleep();
}
private void sleep() {
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
@NonNull
private ViewInteraction getView(@IdRes int id) {
return onView(withId(id)).inRoot(rootMatcher);
}
}
================================================
FILE: appdistribution/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".java.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme">
</activity>
<activity
android:name=".kotlin.KotlinMainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme">
</activity>
<activity android:name=".EntryChoiceActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: appdistribution/app/src/main/java/com/google/firebase/appdistributionquickstart/EntryChoiceActivity.kt
================================================
package com.google.firebase.appdistributionquickstart
import android.content.Intent
import com.firebase.example.internal.BaseEntryChoiceActivity
import com.firebase.example.internal.Choice
import com.google.firebase.appdistributionquickstart.java.MainActivity
import com.google.firebase.appdistributionquickstart.kotlin.KotlinMainActivity
class EntryChoiceActivity : BaseEntryChoiceActivity() {
override fun getChoices(): List<Choice> {
return listOf(
Choice(
"Java",
"Run the Firebase App Distribution quickstart written in Java.",
Intent(this, MainActivity::class.java),
),
Choice(
"Kotlin",
"Run the Firebase App Distribution quickstart written in Kotlin.",
Intent(this, KotlinMainActivity::class.java),
),
)
}
}
================================================
FILE: appdistribution/app/src/main/java/com/google/firebase/appdistributionquickstart/java/MainActivity.java
================================================
package com.google.firebase.appdistributionquickstart.java;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.google.firebase.appdistribution.FirebaseAppDistribution;
import com.google.firebase.appdistribution.FirebaseAppDistributionException;
import com.google.firebase.appdistributionquickstart.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "AppDistribution-Quickstart";
private FirebaseAppDistribution mFirebaseAppDistribution;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
mFirebaseAppDistribution = FirebaseAppDistribution.getInstance();
}
@Override
public void onResume() {
super.onResume();
mFirebaseAppDistribution.updateIfNewReleaseAvailable()
.addOnProgressListener(updateProgress -> {
// (Optional) Implement custom progress updates in addition to
// automatic NotificationManager updates.
})
.addOnFailureListener(e -> {
if (e instanceof FirebaseAppDistributionException) {
// Handle exception.
}
});
}
}
================================================
FILE: appdistribution/app/src/main/java/com/google/firebase/appdistributionquickstart/kotlin/KotlinMainActivity.kt
================================================
package com.google.firebase.appdistributionquickstart.kotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.appdistribution.FirebaseAppDistribution
import com.google.firebase.appdistribution.FirebaseAppDistributionException
import com.google.firebase.appdistribution.appDistribution
import com.google.firebase.appdistributionquickstart.databinding.ActivityMainBinding
import com.google.firebase.Firebase
class KotlinMainActivity : AppCompatActivity() {
private lateinit var firebaseAppDistribution: FirebaseAppDistribution
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
firebaseAppDistribution = Firebase.appDistribution
}
override fun onResume() {
super.onResume()
firebaseAppDistribution.updateIfNewReleaseAvailable()
.addOnProgressListener { updateProgress ->
// (Optional) Implement custom progress updates in addition to
// automatic NotificationManager updates.
}
.addOnFailureListener { e ->
if (e is FirebaseAppDistributionException) {
// Handle exception.
}
}
}
companion object {
private const val TAG = "AppDistribution-Quickstart"
}
}
================================================
FILE: appdistribution/app/src/main/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>
================================================
FILE: appdistribution/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>
================================================
FILE: appdistribution/app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:src="@drawable/firebase_lockup_400"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:text="@string/textview_text"
android:textSize="18sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
================================================
FILE: appdistribution/app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#039BE5</color>
<color name="colorPrimaryDark">#0288D1</color>
<color name="colorAccent">#FFA000</color>
<color name="primary_text">#212121</color>
<color name="secondary_text">#727272</color>
<color name="icons">#212121</color>
<color name="divider">#B6B6B6</color>
<color name="grey_500">#9E9E9E</color>
</resources>
================================================
FILE: appdistribution/app/src/main/res/values/dimens.xml
================================================
<resources>
<dimen name="fab_margin">16dp</dimen>
</resources>
================================================
FILE: appdistribution/app/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">App Distribution Quickstart</string>
<string name="textview_text">Welcome to the Firebase App Distribution Quickstart app. Press the button to trigger an analytics event!</string>
<string name="installation_id_fmt">Firebase Installation ID: %s</string>
</resources>
================================================
FILE: appdistribution/app/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<!-- Dark Buttons -->
<style name="ThemeOverlay.MyDarkButton" parent="ThemeOverlay.AppCompat.Dark">
<item name="colorButtonNormal">@color/colorAccent</item>
<item name="android:layout_marginRight">4dp</item>
<item name="android:layout_marginLeft">4dp</item>
<item name="android:textColor">@android:color/white</item>
</style>
</resources>
================================================
FILE: appdistribution/build.gradle.kts
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.google.services) apply false
}
allprojects {
repositories {
mavenLocal()
google()
mavenCentral()
}
}
tasks {
register("clean", Delete::class) {
delete(rootProject.layout.buildDirectory)
}
}
================================================
FILE: appdistribution/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: appdistribution/gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
android.useAndroidX=true
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
================================================
FILE: appdistribution/gradlew
================================================
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
================================================
FILE: appdistribution/gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: appdistribution/settings.gradle.kts
================================================
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
include(":app")
// Required so that gradle can resolve these dependencies even when
// building only a single project.
include(":internal:lintchecks")
project(":internal:lintchecks").projectDir = file("../internal/lintchecks")
include(":internal:lint")
project(":internal:lint").projectDir = file("../internal/lint")
include(":internal:chooserx")
project(":internal:chooserx").projectDir = file("../internal/chooserx")
================================================
FILE: auth/.gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
service_account.json
================================================
FILE: auth/README.md
================================================
Firebase Auth Quickstart
==============================
Introduction
------------
- [Read more about Firebase Auth](https://firebase.google.com)
Getting Started
---------------
- [Add Firebase to your Android Project](https://firebase.google.com/docs/android/setup).
### Google Sign In Setup
- Go to the [Firebase Console][fir-console] and navigate to your project:
- Select the **Auth** panel and then click the **Sign In Method** tab.
- Click **Google** and turn on the **Enable** switch, then click **Save**.
- Run the sample app on your device or emulator.
- Select **GoogleSignInActivity** from the main screen.
- Click the **Sign In** button to begin.
### Facebook Login Setup
- Go to the [Meta for Developers Site](https://developers.facebook.com) and follow all
instructions to set up a new Android app.
- When asked for a package name, use
`com.google.firebase.quickstart.auth`.
- When asked for a main class name,
use `com.google.firebase.quickstart.auth.kotlin.MainActivity`.
- Go to the [Firebase Console][fir-console] and navigate to your project:
- Select the **Auth** panel and then click the **Sign In Method** tab.
- Click **Facebook** and turn on the **Enable** switch, then click **Save**.
- Enter your Facebook **App Id** and **App Secret** and click **Save**.
- Open the file `app/src/main/res/values/ids.xml` and replace the values of `facebook_app_id` and `facebook_client_token` with the ID of the Facebook app you just created and the client token respectively.
- Run the app on your device or emulator.
- Select the **FacebookLoginFragment** from the main screen.
- Click the **Sign In** button to begin.
- If you see text that says Facebook is disabled, make sure you are running
either the **facebookDebug** or **facebookRelease** variants of this sample.
### Email/Password Setup
- Go to the [Firebase Console][fir-console] and navigate to your project:
- Select the **Auth** panel and then click the **Sign In Method** tab.
- Click **Email/Password** and turn on the **Enable** switch, then click **Save**.
- Under **Authorized Domains** click **Add Domain** and add `auth.example.com`.
- Run the app on your device or emulator.
- Select **EmailPasswordActivity** from the main screen.
- Fill in your desired email and password and click **Create Account** to begin.
### Passwordless Setup
- Go to the [Firebase Console][fir-console] and navigate to your project:
- Select the **Auth** panel and then click the **Sign In Method** tab.
- Click **Email/Password** and turn on the **Enable** switch.
- Turn on the **Email Link (passwordless sign-in)** switch, then click **Save**.
- Replace your-project-id in the AndroidManifest.xml file with your project ID.
- Run the app on your device or emulator.
- Select **PasswordlessActivity** from the main screen.
- Fill in your desired email and click **Send Link** to begin.
### Phone Authentication Setup
- Go to the [Firebase Console][fir-console] and navigate to your project:
- Select the **Auth** panel and then click the **Sign In Method** tab.
- Click **Phone** and turn on the **Enable** switch, then click **Save**.
- Run the app on your physical device:
- Select **PhoneAuthActivity** from the main screen.
- Enter your phone number and click **Verify** to begin.
### Custom Authentication Setup
- Go to the [Google Developers Console](https://console.developers.google.com/project) and navigate to your project:
- Click on the **Service accounts** tab in the left.
- Click on the **Create Service Account** on the top.
- Enter desired service account name and click on the **Create** button.
- Once the service account is created, click on the **Options**.
- Choose **JSON** as the key type then click on the **Create** button.
- You should now have a new JSON file for your service account in your Downloads directory.
- Open the file `web/auth.html` using your web browser.
- Click **Choose File** and upload the JSON file you just downloaded.
- Enter any User ID and click **Generate**.
- Copy the text from the **ADB Command** section. This will be required later on.
- Run the Android application on your Android device or emulator.
- Select **CustomAuthActivity** from the main screen.
- Run the text copied from the **ADB Command** section of the web page in the steps above. This will update the Custom Token field of the running app.
- Click **Sign In** to sign in to Firebase User Management with the generated JWT. You should
see the User ID you entered when generating the token.
### Generic OAuth Sign In (Microsoft, Apple, Yahoo, Twitter, etc)
#### Microsoft
- Follow the [instructions](https://firebase.google.com/docs/auth/android/microsoft-oauth#before_you_begin)
to enable Microsoft authentication in the Firebase console.
- Run the Android application on your Android device or emulator.
- Select **GenericIdpActivity** from the main screen.
- Select **Microsoft** in the dropdown.
- Hit the sign in button and proceed through the login flow.
#### Apple
- Follow the [instructions](https://firebase.google.com/docs/auth/android/apple-oauth#before_you_begin)
to enable Apple authentication in the Firebase console.
- Run the Android application on your Android device or emulator.
- Select **GenericIdpActivity** from the main screen.
- Select **Apple** in the dropdown.
- Hit the sign in button and proceed through the login flow.
#### Yahoo
- Follow the [instructions](https://firebase.google.com/docs/auth/android/yahoo-oauth#before_you_begin)
to enable Yahoo authentication in the Firebase console.
- Run the Android application on your Android device or emulator.
- Select **GenericIdpActivity** from the main screen.
- Select **Yahoo** in the dropdown.
- Hit the sign in button and proceed through the login flow.
#### Twitter
- Follow the [instructions](https://firebase.google.com/docs/auth/android/twitter-login#before_you_begin)
to enable Twitter authentication in the Firebase console.
- Run the Android application on your Android device or emulator.
- Select **GenericIdpActivity** from the main screen.
- Select **Twitter** in the dropdown.
- Hit the sign in button and proceed through the login flow.
### Multi Factor Authentication
**Note**: Multi Factor authentication only works for apps using
[Google Cloud Identity Platform](https://cloud.google.com/identity-platform/docs/android/mfa),
a paid service. If you are only using Firebase Authentication this sample will not work for you.
- Run the app on your physical device (emulators will not work)
- Select **MultiFactorAuthActivity** from the main screen.
- Sign in (if necessary).
- Verify your email (if necessary).
- Hit **Enroll MFA** to begin enrolling an SMS second factor.
Result
-----------
<img src="app/src/screen.png" height="534" width="300"/>
Support
-------
- [Stack Overflow](https://stackoverflow.com/questions/tagged/firebase-authentication)
- [Firebase Support](https://firebase.google.com/support/)
License
-------
Copyright 2020 Google, Inc.
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
additional information regarding copyright ownership. The ASF licenses this
file to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
[fir-console]: https://console.firebase.google.com
================================================
FILE: auth/app/.gitignore
================================================
/build
================================================
FILE: auth/app/build.gradle.kts
================================================
import com.android.build.gradle.internal.tasks.factory.dependsOn
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.google.services)
}
tasks {
check.dependsOn("assembleDebugAndroidTest")
}
android {
namespace= "com.google.firebase.quickstart.auth"
compileSdk = 36
flavorDimensions += "minSdkVersion"
defaultConfig {
applicationId = "com.google.firebase.quickstart.auth"
minSdk = 23
targetSdk = 36
versionCode = 1
versionName = "1.0"
multiDexEnabled = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
buildFeatures {
viewBinding = true
buildConfig = true
}
}
dependencies {
implementation(project(":internal:chooserx"))
implementation(project(":internal:lintchecks"))
implementation("androidx.activity:activity-ktx:1.12.1")
implementation("androidx.constraintlayout:constraintlayout:2.2.1")
implementation("androidx.vectordrawable:vectordrawable-animated:1.2.0")
implementation("com.google.android.material:material:1.13.0")
implementation("androidx.navigation:navigation-fragment-ktx:2.9.6")
implementation("androidx.navigation:navigation-ui-ktx:2.9.6")
// Import the Firebase BoM (see: https://firebase.google.com/docs/android/learn-more#bom)
implementation(platform("com.google.firebase:firebase-bom:34.7.0"))
// Firebase Authentication
implementation("com.google.firebase:firebase-auth")
// Google Identity Services SDK (only required for Auth with Google)
implementation("androidx.credentials:credentials:1.5.0")
implementation("androidx.credentials:credentials-play-services-auth:1.5.0")
implementation("com.google.android.libraries.identity.googleid:googleid:1.1.1")
// Firebase UI
// Used in FirebaseUIActivity.
implementation("com.firebaseui:firebase-ui-auth:9.1.1")
// Facebook Android SDK (only required for Facebook Login)
// Used in FacebookLoginActivity.
implementation("com.facebook.android:facebook-login:13.2.0")
implementation("androidx.browser:browser:1.5.0")
androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0")
androidTestImplementation("androidx.test:rules:1.7.0")
androidTestImplementation("androidx.test:runner:1.7.0")
}
================================================
FILE: auth/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-keepattributes Signature
-keepattributes *Annotation*
-keepattributes EnclosingMethod
-keepattributes InnerClasses
# Required for Twitter Authentication
# https://docs.fabric.io/android/twitter/twitter.html#set-up-kit
-dontwarn com.squareup.okhttp.**
-dontwarn com.google.appengine.api.urlfetch.**
-dontwarn rx.**
-dontwarn retrofit.**
-dontwarn retrofit2.**
-dontwarn okio.**
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-keep class retrofit.** { *; }
-keepclasseswithmembers class * {
@retrofit.http.* <methods>;
}
================================================
FILE: auth/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".EntryChoiceActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".java.MainActivity" />
<activity android:name=".kotlin.MainActivity" />
<activity
android:name=".java.PasswordlessActivity"
android:label="@string/label_passwordless"
android:launchMode="singleTop"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data
android:host="your-project-id.firebaseapp.com"
android:scheme="https" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".kotlin.PasswordlessActivity"
android:label="@string/label_passwordless"
android:launchMode="singleTop"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data
android:host="your-project-id.firebaseapp.com"
android:scheme="https" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!-- Facebook Configuration -->
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id"
tools:replace="android:value" />
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="@string/facebook_client_token"/>
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
tools:replace="android:theme" />
</application>
</manifest>
================================================
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/EntryChoiceActivity.kt
================================================
package com.google.firebase.quickstart.auth
import android.content.Intent
import com.firebase.example.internal.BaseEntryChoiceActivity
import com.firebase.example.internal.Choice
class EntryChoiceActivity : BaseEntryChoiceActivity() {
override fun getChoices(): List<Choice> {
return listOf(
Choice(
"Java",
"Run the Firebase Auth quickstart written in Java.",
Intent(this, com.google.firebase.quickstart.auth.java.MainActivity::class.java),
),
Choice(
"Kotlin",
"Run the Firebase Auth quickstart written in Kotlin.",
Intent(this, com.google.firebase.quickstart.auth.kotlin.MainActivity::class.java),
),
)
}
}
================================================
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/AnonymousAuthFragment.java
================================================
/**
* Copyright 2021 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.firebase.quickstart.auth.java;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.EmailAuthProvider;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.quickstart.auth.R;
import com.google.firebase.quickstart.auth.databinding.FragmentAnonymousAuthBinding;
public class AnonymousAuthFragment extends BaseFragment {
private static final String TAG = "AnonymousAuth";
private FirebaseAuth mAuth;
private FragmentAnonymousAuthBinding mBinding;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mBinding = FragmentAnonymousAuthBinding.inflate(inflater, container, false);
return mBinding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Initialize Firebase Auth
mAuth = FirebaseAuth.getInstance();
// Fields
setProgressBar(mBinding.progressBar);
// Click listeners
mBinding.buttonAnonymousSignIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
signInAnonymously();
}
});
mBinding.buttonAnonymousSignOut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
signOut();
}
});
mBinding.buttonLinkAccount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
linkAccount();
}
});
}
@Override
public void onStart() {
super.onStart();
// Check if user is signed in (non-null) and update UI accordingly.
FirebaseUser currentUser = mAuth.getCurrentUser();
updateUI(currentUser);
}
private void signInAnonymously() {
showProgressBar();
mAuth.signInAnonymously()
.addOnCompleteListener(requireActivity(), new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInAnonymously:success");
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInAnonymously:failure", task.getException());
Toast.makeText(getContext(), "Authentication failed.",
Toast.LENGTH_SHORT).show();
updateUI(null);
}
hideProgressBar();
}
});
}
private void signOut() {
mAuth.signOut();
updateUI(null);
}
private void linkAccount() {
// Make sure form is valid
if (!validateLinkForm()) {
return;
}
// Get email and password from form
String email = mBinding.fieldEmail.getText().toString();
String password = mBinding.fieldPassword.getText().toString();
// Create EmailAuthCredential with email and password
AuthCredential credential = EmailAuthProvider.getCredential(email, password);
// Link the anonymous user to the email credential
showProgressBar();
mAuth.getCurrentUser().linkWithCredential(credential)
.addOnCompleteListener(requireActivity(), new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "linkWithCredential:success");
FirebaseUser user = task.getResult().getUser();
updateUI(user);
} else {
Log.w(TAG, "linkWithCredential:failure", task.getException());
Toast.makeText(getContext(), "Authentication failed.",
Toast.LENGTH_SHORT).show();
updateUI(null);
}
hideProgressBar();
}
});
}
private boolean validateLinkForm() {
boolean valid = true;
String email = mBinding.fieldEmail.getText().toString();
if (TextUtils.isEmpty(email)) {
mBinding.fieldEmail.setError("Required.");
valid = false;
} else {
mBinding.fieldEmail.setError(null);
}
String password = mBinding.fieldPassword.getText().toString();
if (TextUtils.isEmpty(password)) {
mBinding.fieldPassword.setError("Required.");
valid = false;
} else {
mBinding.fieldPassword.setError(null);
}
return valid;
}
private void updateUI(FirebaseUser user) {
hideProgressBar();
TextView idView = mBinding.anonymousStatusId;
TextView emailView = mBinding.anonymousStatusEmail;
boolean isSignedIn = (user != null);
// Status text
if (isSignedIn) {
idView.setText(getString(R.string.id_fmt, user.getUid()));
emailView.setText(getString(R.string.email_fmt, user.getEmail()));
} else {
idView.setText(R.string.signed_out);
emailView.setText(null);
}
// Button visibility
mBinding.buttonAnonymousSignIn.setEnabled(!isSignedIn);
mBinding.buttonAnonymousSignOut.setEnabled(isSignedIn);
mBinding.buttonLinkAccount.setEnabled(isSignedIn);
}
@Override
public void onDestroyView() {
super.onDestroyView();
mBinding = null;
}
}
================================================
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/BaseActivity.java
================================================
package com.google.firebase.quickstart.auth.java;
import android.content.Context;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ProgressBar;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AppCompatActivity;
public class BaseActivity extends AppCompatActivity {
@VisibleForTesting
public ProgressBar mProgressBar;
public void setProgressBar(ProgressBar progressBar) {
mProgressBar = progressBar;
}
public void showProgressBar() {
if (mProgressBar != null) {
mProgressBar.setVisibility(View.VISIBLE);
}
}
public void hideProgressBar() {
if (mProgressBar != null) {
mProgressBar.setVisibility(View.INVISIBLE);
}
}
public void hideKeyboard(View view) {
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
@Override
public void onStop() {
super.onStop();
hideProgressBar();
}
}
================================================
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/BaseFragment.java
================================================
package com.google.firebase.quickstart.auth.java;
import android.content.Context;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ProgressBar;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
public class BaseFragment extends Fragment {
@VisibleForTesting
public ProgressBar mProgressBar;
public void setProgressBar(ProgressBar progressBar) {
mProgressBar = progressBar;
}
public void showProgressBar() {
if (mProgressBar != null) {
mProgressBar.setVisibility(View.VISIBLE);
}
}
public void hideProgressBar() {
if (mProgressBar != null) {
mProgressBar.setVisibility(View.INVISIBLE);
}
}
public void hideKeyboard(View view) {
final InputMethodManager imm = (InputMethodManager) requireActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
@Override
public void onStop() {
super.onStop();
hideProgressBar();
}
}
================================================
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/ChooserFragment.java
================================================
/**
* Copyright 2021 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed
gitextract_q82ekbdt/
├── .editorconfig
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── config.yml
│ │ └── quickstart_issue.md
│ └── workflows/
│ └── android.yml
├── .gitignore
├── .google/
│ └── packaging.yaml
├── .opensource/
│ └── project.json
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── admob/
│ ├── .gitignore
│ ├── .google/
│ │ └── packaging.yaml
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── samples/
│ │ │ └── quickstart/
│ │ │ └── admobexample/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── FirstFragment.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── SecondFragment.java
│ │ │ └── kotlin/
│ │ │ ├── FirstFragment.kt
│ │ │ ├── MainActivity.kt
│ │ │ └── SecondFragment.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ ├── fragment_first.xml
│ │ │ └── fragment_second.xml
│ │ ├── navigation/
│ │ │ ├── nav_graph_java.xml
│ │ │ └── nav_graph_kotlin.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── analytics/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── analytics/
│ │ │ └── MainActivityTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── analytics/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── ImageFragment.java
│ │ │ │ ├── ImageInfo.java
│ │ │ │ └── MainActivity.java
│ │ │ └── kotlin/
│ │ │ ├── ImageFragment.kt
│ │ │ ├── ImageInfo.kt
│ │ │ └── MainActivity.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ └── circle.xml
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ └── fragment_main.xml
│ │ ├── menu/
│ │ │ └── main.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-v21/
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── appdistribution/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── appdistributionquickstart/
│ │ │ └── InstrumentedTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── appdistributionquickstart/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ └── MainActivity.java
│ │ │ └── kotlin/
│ │ │ └── KotlinMainActivity.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ └── ic_launcher_background.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── auth/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── auth/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── AnonymousAuthFragment.java
│ │ │ │ ├── BaseActivity.java
│ │ │ │ ├── BaseFragment.java
│ │ │ │ ├── ChooserFragment.java
│ │ │ │ ├── CustomAuthFragment.java
│ │ │ │ ├── EmailPasswordFragment.java
│ │ │ │ ├── FacebookLoginFragment.java
│ │ │ │ ├── FirebaseUIFragment.java
│ │ │ │ ├── GenericIdpFragment.java
│ │ │ │ ├── GoogleSignInFragment.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MultiFactorEnrollFragment.java
│ │ │ │ ├── MultiFactorFragment.java
│ │ │ │ ├── MultiFactorSignInFragment.java
│ │ │ │ ├── MultiFactorUnenrollFragment.java
│ │ │ │ ├── PasswordlessActivity.java
│ │ │ │ ├── PhoneAuthFragment.java
│ │ │ │ └── TokenBroadcastReceiver.java
│ │ │ └── kotlin/
│ │ │ ├── AnonymousAuthFragment.kt
│ │ │ ├── BaseActivity.kt
│ │ │ ├── BaseFragment.kt
│ │ │ ├── ChooserFragment.kt
│ │ │ ├── CustomAuthFragment.kt
│ │ │ ├── EmailPasswordFragment.kt
│ │ │ ├── FacebookLoginFragment.kt
│ │ │ ├── FirebaseUIFragment.kt
│ │ │ ├── GenericIdpFragment.kt
│ │ │ ├── GoogleSignInFragment.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── MultiFactorEnrollFragment.kt
│ │ │ ├── MultiFactorFragment.kt
│ │ │ ├── MultiFactorSignInFragment.kt
│ │ │ ├── MultiFactorUnenrollFragment.kt
│ │ │ ├── PasswordlessActivity.kt
│ │ │ ├── PhoneAuthFragment.kt
│ │ │ └── TokenBroadcastReceiver.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_passwordless.xml
│ │ │ ├── fragment_anonymous_auth.xml
│ │ │ ├── fragment_chooser.xml
│ │ │ ├── fragment_custom.xml
│ │ │ ├── fragment_emailpassword.xml
│ │ │ ├── fragment_facebook.xml
│ │ │ ├── fragment_firebase_ui.xml
│ │ │ ├── fragment_generic_idp.xml
│ │ │ ├── fragment_google.xml
│ │ │ ├── fragment_multi_factor.xml
│ │ │ ├── fragment_multi_factor_sign_in.xml
│ │ │ ├── fragment_passwordless.xml
│ │ │ ├── fragment_phone_auth.xml
│ │ │ └── item_spinner_list.xml
│ │ ├── navigation/
│ │ │ ├── nav_graph_java.xml
│ │ │ └── nav_graph_kotlin.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── ids.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-land/
│ │ │ └── dimens.xml
│ │ ├── values-v21/
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── settings.gradle.kts
│ └── web/
│ └── auth.html
├── build.gradle.kts
├── build_pull_request.sh
├── config/
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── samples/
│ │ │ └── quickstart/
│ │ │ └── config/
│ │ │ └── MainActivityTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── samples/
│ │ │ └── quickstart/
│ │ │ └── config/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ └── MainActivity.java
│ │ │ └── kotlin/
│ │ │ └── MainActivity.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-w820dp/
│ │ │ └── dimens.xml
│ │ └── xml/
│ │ └── remote_config_defaults.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── copy_mock_google_services_json.sh
├── crash/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ ├── src/
│ │ │ ├── androidTest/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── google/
│ │ │ │ └── samples/
│ │ │ │ └── quickstart/
│ │ │ │ └── crash/
│ │ │ │ └── MainActivityTest.java
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── google/
│ │ │ │ └── samples/
│ │ │ │ └── quickstart/
│ │ │ │ └── crash/
│ │ │ │ ├── EntryChoiceActivity.kt
│ │ │ │ ├── java/
│ │ │ │ │ ├── CustomKeySamples.java
│ │ │ │ │ └── MainActivity.java
│ │ │ │ └── kotlin/
│ │ │ │ ├── CustomKeySamples.kt
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── layout/
│ │ │ │ └── activity_main.xml
│ │ │ ├── values/
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ └── values-w820dp/
│ │ │ └── dimens.xml
│ │ └── test-proguard-rules.pro
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── database/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── database/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── BaseFragment.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MainFragment.java
│ │ │ │ ├── NewPostFragment.java
│ │ │ │ ├── PostDetailFragment.java
│ │ │ │ ├── SignInFragment.java
│ │ │ │ ├── listfragments/
│ │ │ │ │ ├── MyPostsFragment.java
│ │ │ │ │ ├── MyTopPostsFragment.java
│ │ │ │ │ ├── PostListFragment.java
│ │ │ │ │ └── RecentPostsFragment.java
│ │ │ │ ├── models/
│ │ │ │ │ ├── Comment.java
│ │ │ │ │ ├── Post.java
│ │ │ │ │ └── User.java
│ │ │ │ └── viewholder/
│ │ │ │ ├── CommentViewHolder.java
│ │ │ │ └── PostViewHolder.java
│ │ │ └── kotlin/
│ │ │ ├── BaseFragment.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── MainFragment.kt
│ │ │ ├── NewPostFragment.kt
│ │ │ ├── PostDetailFragment.kt
│ │ │ ├── SignInFragment.kt
│ │ │ ├── listfragments/
│ │ │ │ ├── MyPostsFragment.kt
│ │ │ │ ├── MyTopPostsFragment.kt
│ │ │ │ ├── PostListFragment.kt
│ │ │ │ └── RecentPostsFragment.kt
│ │ │ ├── models/
│ │ │ │ ├── Comment.kt
│ │ │ │ ├── Post.kt
│ │ │ │ └── User.kt
│ │ │ └── viewholder/
│ │ │ ├── CommentViewHolder.kt
│ │ │ └── PostViewHolder.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ ├── fragment_all_posts.xml
│ │ │ ├── fragment_main.xml
│ │ │ ├── fragment_new_post.xml
│ │ │ ├── fragment_post_detail.xml
│ │ │ ├── fragment_sign_in.xml
│ │ │ ├── include_post_author.xml
│ │ │ ├── include_post_text.xml
│ │ │ ├── item_comment.xml
│ │ │ └── item_post.xml
│ │ ├── menu/
│ │ │ └── menu_main.xml
│ │ ├── navigation/
│ │ │ ├── nav_graph_java.xml
│ │ │ └── nav_graph_kotlin.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-v21/
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── dataconnect/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── example/
│ │ │ └── dataconnect/
│ │ │ ├── MainActivity.kt
│ │ │ ├── feature/
│ │ │ │ ├── actordetail/
│ │ │ │ │ ├── ActorDetailScreen.kt
│ │ │ │ │ ├── ActorDetailUIState.kt
│ │ │ │ │ └── ActorDetailViewModel.kt
│ │ │ │ ├── moviedetail/
│ │ │ │ │ ├── MovieDetailScreen.kt
│ │ │ │ │ ├── MovieDetailUIState.kt
│ │ │ │ │ ├── MovieDetailViewModel.kt
│ │ │ │ │ └── UserReviews.kt
│ │ │ │ ├── movies/
│ │ │ │ │ ├── MoviesScreen.kt
│ │ │ │ │ ├── MoviesUIState.kt
│ │ │ │ │ └── MoviesViewModel.kt
│ │ │ │ ├── profile/
│ │ │ │ │ ├── AuthScreen.kt
│ │ │ │ │ ├── ProfileScreen.kt
│ │ │ │ │ ├── ProfileUIState.kt
│ │ │ │ │ └── ProfileViewModel.kt
│ │ │ │ └── search/
│ │ │ │ └── Navigation.kt
│ │ │ └── ui/
│ │ │ ├── components/
│ │ │ │ ├── ActorsList.kt
│ │ │ │ ├── ErrorCard.kt
│ │ │ │ ├── LoadingScreen.kt
│ │ │ │ ├── MoviesList.kt
│ │ │ │ ├── ReviewCard.kt
│ │ │ │ └── ToggleButton.kt
│ │ │ └── theme/
│ │ │ ├── Color.kt
│ │ │ ├── Theme.kt
│ │ │ └── Type.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── firebase_data_connect.xml
│ │ │ └── ic_launcher_background.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── themes.xml
│ │ └── xml/
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ ├── build.gradle.kts
│ ├── dataconnect/
│ │ ├── dataconnect.yaml
│ │ ├── movie-connector/
│ │ │ ├── connector.yaml
│ │ │ ├── mutations.gql
│ │ │ └── queries.gql
│ │ ├── moviedata_insert.gql
│ │ └── schema/
│ │ └── schema.gql
│ ├── firebase.json
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── dynamiclinks/
│ └── README.md
├── firebase-ai/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── ai/
│ │ │ ├── MainActivity.kt
│ │ │ ├── feature/
│ │ │ │ ├── live/
│ │ │ │ │ ├── BidiViewModel.kt
│ │ │ │ │ ├── StreamAudioViewModel.kt
│ │ │ │ │ └── StreamVideoViewModel.kt
│ │ │ │ ├── media/
│ │ │ │ │ └── imagen/
│ │ │ │ │ ├── ImagenGenerationViewModel.kt
│ │ │ │ │ ├── ImagenInpaintingViewModel.kt
│ │ │ │ │ ├── ImagenOutpaintingViewModel.kt
│ │ │ │ │ ├── ImagenStyleTransferViewModel.kt
│ │ │ │ │ ├── ImagenSubjectReferenceViewModel.kt
│ │ │ │ │ ├── ImagenTemplateViewModel.kt
│ │ │ │ │ └── ImagenViewModel.kt
│ │ │ │ └── text/
│ │ │ │ ├── AudioSummarizationViewModel.kt
│ │ │ │ ├── AudioTranslationViewModel.kt
│ │ │ │ ├── ChatViewModel.kt
│ │ │ │ ├── CourseRecommendationsViewModel.kt
│ │ │ │ ├── DocumentComparisonViewModel.kt
│ │ │ │ ├── GoogleSearchGroundingViewModel.kt
│ │ │ │ ├── ImageBlogCreatorViewModel.kt
│ │ │ │ ├── ImageGenerationViewModel.kt
│ │ │ │ ├── ServerPromptTemplateViewModel.kt
│ │ │ │ ├── SvgViewModel.kt
│ │ │ │ ├── ThinkingChatViewModel.kt
│ │ │ │ ├── TranslationViewModel.kt
│ │ │ │ ├── TravelTipsViewModel.kt
│ │ │ │ ├── VideoHashtagGeneratorViewModel.kt
│ │ │ │ ├── VideoSummarizationViewModel.kt
│ │ │ │ ├── WeatherChatViewModel.kt
│ │ │ │ └── functioncalling/
│ │ │ │ └── WeatherRepository.kt
│ │ │ └── ui/
│ │ │ ├── CameraView.kt
│ │ │ ├── ChatScreen.kt
│ │ │ ├── ChatUiState.kt
│ │ │ ├── ImagenScreen.kt
│ │ │ ├── ImagenUiState.kt
│ │ │ ├── ServerPromptScreen.kt
│ │ │ ├── ServerPromptUiState.kt
│ │ │ ├── StreamRealtimeScreen.kt
│ │ │ ├── StreamRealtimeVideoScreen.kt
│ │ │ ├── SvgScreen.kt
│ │ │ ├── SvgUiState.kt
│ │ │ ├── navigation/
│ │ │ │ ├── FirebaseAISamples.kt
│ │ │ │ ├── MainMenuScreen.kt
│ │ │ │ └── Sample.kt
│ │ │ └── theme/
│ │ │ ├── Color.kt
│ │ │ ├── Theme.kt
│ │ │ └── Type.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── round_arrow_drop_down_24.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── mipmap-anydpi-v26/
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── themes.xml
│ │ └── xml/
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── firestore/
│ ├── .gitignore
│ ├── CONTRIBUTING.md
│ ├── LICENSE
│ ├── README.md
│ ├── accounts.json
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ ├── src/
│ │ │ ├── androidTest/
│ │ │ │ └── AndroidManifest.xml
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── google/
│ │ │ │ └── firebase/
│ │ │ │ └── example/
│ │ │ │ └── fireeats/
│ │ │ │ ├── EntryChoiceActivity.kt
│ │ │ │ ├── java/
│ │ │ │ │ ├── FilterDialogFragment.java
│ │ │ │ │ ├── Filters.java
│ │ │ │ │ ├── MainActivity.java
│ │ │ │ │ ├── MainFragment.java
│ │ │ │ │ ├── RatingDialogFragment.java
│ │ │ │ │ ├── RestaurantDetailFragment.java
│ │ │ │ │ ├── adapter/
│ │ │ │ │ │ ├── FirestoreAdapter.java
│ │ │ │ │ │ ├── RatingAdapter.java
│ │ │ │ │ │ └── RestaurantAdapter.java
│ │ │ │ │ ├── model/
│ │ │ │ │ │ ├── Rating.java
│ │ │ │ │ │ └── Restaurant.java
│ │ │ │ │ ├── util/
│ │ │ │ │ │ ├── RatingUtil.java
│ │ │ │ │ │ └── RestaurantUtil.java
│ │ │ │ │ └── viewmodel/
│ │ │ │ │ └── MainActivityViewModel.java
│ │ │ │ └── kotlin/
│ │ │ │ ├── FilterDialogFragment.kt
│ │ │ │ ├── Filters.kt
│ │ │ │ ├── MainActivity.kt
│ │ │ │ ├── MainFragment.kt
│ │ │ │ ├── RatingDialogFragment.kt
│ │ │ │ ├── RestaurantDetailFragment.kt
│ │ │ │ ├── adapter/
│ │ │ │ │ ├── FirestoreAdapter.kt
│ │ │ │ │ ├── RatingAdapter.kt
│ │ │ │ │ └── RestaurantAdapter.kt
│ │ │ │ ├── model/
│ │ │ │ │ ├── Rating.kt
│ │ │ │ │ └── Restaurant.kt
│ │ │ │ ├── util/
│ │ │ │ │ ├── RatingUtil.kt
│ │ │ │ │ └── RestaurantUtil.kt
│ │ │ │ └── viewmodel/
│ │ │ │ └── MainActivityViewModel.kt
│ │ │ └── res/
│ │ │ ├── anim/
│ │ │ │ ├── slide_in_from_left.xml
│ │ │ │ ├── slide_in_from_right.xml
│ │ │ │ ├── slide_out_to_left.xml
│ │ │ │ └── slide_out_to_right.xml
│ │ │ ├── drawable/
│ │ │ │ ├── bg_shadow.xml
│ │ │ │ ├── gradient_up.xml
│ │ │ │ ├── ic_add_white_24px.xml
│ │ │ │ ├── ic_arrow_back_white_24px.xml
│ │ │ │ ├── ic_close_white_24px.xml
│ │ │ │ ├── ic_fastfood_white_24dp.xml
│ │ │ │ ├── ic_filter_list_white_24px.xml
│ │ │ │ ├── ic_local_dining_white_24px.xml
│ │ │ │ ├── ic_monetization_on_white_24px.xml
│ │ │ │ ├── ic_place_white_24px.xml
│ │ │ │ ├── ic_restaurant_white_24px.xml
│ │ │ │ └── ic_sort_white_24px.xml
│ │ │ ├── layout/
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── dialog_filters.xml
│ │ │ │ ├── dialog_rating.xml
│ │ │ │ ├── fragment_main.xml
│ │ │ │ ├── fragment_restaurant_detail.xml
│ │ │ │ ├── item_rating.xml
│ │ │ │ └── item_restaurant.xml
│ │ │ ├── menu/
│ │ │ │ └── menu_main.xml
│ │ │ ├── navigation/
│ │ │ │ ├── nav_graph_java.xml
│ │ │ │ └── nav_graph_kotlin.xml
│ │ │ ├── values/
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ └── values-v21/
│ │ │ └── styles.xml
│ │ └── test-proguard-rules.pro
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── indexes.json
│ ├── settings.gradle.kts
│ └── test_setup.sh
├── functions/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ ├── src/
│ │ │ ├── androidTest/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── google/
│ │ │ │ └── samples/
│ │ │ │ └── quickstart/
│ │ │ │ └── functions/
│ │ │ │ ├── MainActivityTest.java
│ │ │ │ └── TestAddNumber.java
│ │ │ └── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── google/
│ │ │ │ └── samples/
│ │ │ │ └── quickstart/
│ │ │ │ └── functions/
│ │ │ │ ├── EntryChoiceActivity.kt
│ │ │ │ ├── java/
│ │ │ │ │ ├── FunctionsMessagingService.java
│ │ │ │ │ └── MainActivity.java
│ │ │ │ └── kotlin/
│ │ │ │ ├── FunctionsMessagingService.kt
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── layout/
│ │ │ │ └── activity_main.xml
│ │ │ ├── values/
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── values-w820dp/
│ │ │ │ └── dimens.xml
│ │ │ └── xml/
│ │ │ └── network_security_config.xml
│ │ └── test-proguard-rules.pro
│ ├── build.gradle.kts
│ ├── firebase.json
│ ├── functions/
│ │ ├── .gitignore
│ │ ├── index.js
│ │ ├── package.json
│ │ └── sanitizer.js
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── settings.gradle.kts
│ └── test_setup.sh
├── gradle/
│ ├── libs.versions.toml
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── inappmessaging/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── fiamquickstart/
│ │ │ └── InstrumentedTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── fiamquickstart/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ └── MainActivity.java
│ │ │ └── kotlin/
│ │ │ └── KotlinMainActivity.kt
│ │ └── res/
│ │ ├── drawable/
│ │ │ └── ic_launcher_background.xml
│ │ ├── drawable-v24/
│ │ │ └── ic_launcher_foreground.xml
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── internal/
│ ├── chooserx/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── firebase/
│ │ │ └── example/
│ │ │ └── internal/
│ │ │ ├── BaseEntryChoiceActivity.java
│ │ │ ├── Choice.java
│ │ │ └── ChoiceAdapter.java
│ │ └── res/
│ │ └── layout/
│ │ ├── activity_entry_choice.xml
│ │ └── item_choice.xml
│ ├── lint/
│ │ ├── .gitignore
│ │ ├── bin/
│ │ │ ├── main/
│ │ │ │ └── com/
│ │ │ │ └── firebase/
│ │ │ │ └── lint/
│ │ │ │ ├── HungarianNotationDetector.kt
│ │ │ │ ├── InvalidImportDetector.kt
│ │ │ │ └── QuickstartIssueRegistry.kt
│ │ │ └── test/
│ │ │ └── com/
│ │ │ └── firebase/
│ │ │ └── lint/
│ │ │ └── InvalidImportDetectorTest.kt
│ │ ├── build.gradle.kts
│ │ └── src/
│ │ ├── main/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── firebase/
│ │ │ └── lint/
│ │ │ ├── HungarianNotationDetector.kt
│ │ │ ├── InvalidImportDetector.kt
│ │ │ └── QuickstartIssueRegistry.kt
│ │ └── test/
│ │ └── java/
│ │ └── com/
│ │ └── firebase/
│ │ └── lint/
│ │ └── InvalidImportDetectorTest.kt
│ └── lintchecks/
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── proguard-rules.pro
│ └── src/
│ └── main/
│ └── AndroidManifest.xml
├── messaging/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── fcm/
│ │ │ └── MainActivityEspressoTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── fcm/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MyFirebaseMessagingService.java
│ │ │ │ └── MyWorker.java
│ │ │ └── kotlin/
│ │ │ ├── MainActivity.kt
│ │ │ ├── MyFirebaseMessagingService.kt
│ │ │ └── MyWorker.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── mock-google-services.json
├── perf/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── assets/
│ │ │ └── default_content.txt
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── perfmon/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ └── MainActivity.java
│ │ │ └── kotlin/
│ │ │ └── MainActivity.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
├── scripts/
│ └── checksnippets.py
├── settings.gradle.kts
├── storage/
│ ├── .gitignore
│ ├── README.md
│ ├── app/
│ │ ├── .gitignore
│ │ ├── build.gradle.kts
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── firebasestorage/
│ │ │ ├── MainActivityTest.java
│ │ │ └── ServiceIdlingResource.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── google/
│ │ │ └── firebase/
│ │ │ └── quickstart/
│ │ │ └── firebasestorage/
│ │ │ ├── EntryChoiceActivity.kt
│ │ │ ├── java/
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MyBaseTaskService.java
│ │ │ │ ├── MyDownloadService.java
│ │ │ │ └── MyUploadService.java
│ │ │ └── kotlin/
│ │ │ ├── MainActivity.kt
│ │ │ ├── MyBaseTaskService.kt
│ │ │ ├── MyDownloadService.kt
│ │ │ └── MyUploadService.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ ├── menu/
│ │ │ └── menu_main.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-w820dp/
│ │ │ └── dimens.xml
│ │ └── xml/
│ │ └── file_paths.xml
│ ├── build.gradle.kts
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle.kts
└── vertexai/
└── README.md
SYMBOL INDEX (613 symbols across 83 files)
FILE: admob/app/src/main/java/com/google/samples/quickstart/admobexample/java/FirstFragment.java
class FirstFragment (line 26) | class FirstFragment extends Fragment {
method onCreateView (line 36) | @Nullable
method onViewCreated (line 43) | @Override
method requestNewInterstitial (line 74) | private void requestNewInterstitial() {
method beginSecondActivity (line 112) | private void beginSecondActivity() {
method onPause (line 117) | @Override
method onResume (line 126) | @Override
method onDestroy (line 138) | @Override
method getAdView (line 146) | @VisibleForTesting
method checkIds (line 151) | private void checkIds() {
FILE: admob/app/src/main/java/com/google/samples/quickstart/admobexample/java/MainActivity.java
class MainActivity (line 24) | public class MainActivity extends AppCompatActivity {
method onCreate (line 26) | @Override
FILE: admob/app/src/main/java/com/google/samples/quickstart/admobexample/java/SecondFragment.java
class SecondFragment (line 10) | class SecondFragment extends Fragment {
method onCreateView (line 12) | @Override
FILE: analytics/app/src/androidTest/java/com/google/firebase/quickstart/analytics/MainActivityTest.java
class MainActivityTest (line 28) | @LargeTest
method mainActivityTest (line 35) | @Test
method checkTitleText (line 60) | private void checkTitleText(@StringRes int resId) {
method selectFavoriteFoodIfPossible (line 65) | private void selectFavoriteFoodIfPossible(String food) {
FILE: analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/ImageFragment.java
class ImageFragment (line 34) | public class ImageFragment extends Fragment {
method newInstance (line 45) | public static ImageFragment newInstance(int resId) {
method ImageFragment (line 53) | public ImageFragment() {
method onCreate (line 56) | @Override
method onCreateView (line 64) | @Override
FILE: analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/ImageInfo.java
class ImageInfo (line 22) | public class ImageInfo {
method ImageInfo (line 35) | public ImageInfo(int image, int title, int id) {
FILE: analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/MainActivity.java
class MainActivity (line 51) | public class MainActivity extends AppCompatActivity {
method onCreate (line 87) | @Override
method onResume (line 136) | @Override
method askFavoriteFood (line 146) | private void askFavoriteFood() {
method getUserFavoriteFood (line 166) | private String getUserFavoriteFood() {
method setUserFavoriteFood (line 175) | private void setUserFavoriteFood(String food) {
method onCreateOptionsMenu (line 188) | @Override
method onOptionsItemSelected (line 194) | @Override
method getCurrentImageTitle (line 222) | private String getCurrentImageTitle() {
method getCurrentImageId (line 233) | private String getCurrentImageId() {
method recordImageView (line 243) | private void recordImageView() {
method recordScreenView (line 260) | private void recordScreenView() {
class ImagePagerAdapter (line 276) | public class ImagePagerAdapter extends FragmentStateAdapter {
method ImagePagerAdapter (line 280) | public ImagePagerAdapter(FragmentManager fm, ImageInfo[] infos, Life...
method getPageTitle (line 285) | public CharSequence getPageTitle(int position) {
method createFragment (line 294) | @NonNull
method getItemCount (line 301) | @Override
FILE: appdistribution/app/src/androidTest/java/com/google/firebase/appdistributionquickstart/InstrumentedTest.java
class InstrumentedTest (line 36) | @RunWith(AndroidJUnit4.class)
method setUp (line 44) | @Before
method tearDown (line 49) | @After
method testFiamDisplaysOnForegroundCampaign (line 55) | @Test
method testFiamDisplaysContextualTriggerCampaign (line 61) | @Test
method reopen_app (line 67) | private void reopen_app() {
method press_recent (line 72) | private void press_recent() {
method press_back (line 81) | private void press_back() {
method sleep (line 87) | private void sleep() {
method getView (line 95) | @NonNull
FILE: appdistribution/app/src/main/java/com/google/firebase/appdistributionquickstart/java/MainActivity.java
class MainActivity (line 11) | public class MainActivity extends AppCompatActivity {
method onCreate (line 17) | @Override
method onResume (line 26) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/AnonymousAuthFragment.java
class AnonymousAuthFragment (line 41) | public class AnonymousAuthFragment extends BaseFragment {
method onCreateView (line 48) | @Nullable
method onViewCreated (line 56) | @Override
method onStart (line 86) | @Override
method signInAnonymously (line 94) | private void signInAnonymously() {
method signOut (line 118) | private void signOut() {
method linkAccount (line 123) | private void linkAccount() {
method validateLinkForm (line 159) | private boolean validateLinkForm() {
method updateUI (line 181) | private void updateUI(FirebaseUser user) {
method onDestroyView (line 203) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/BaseActivity.java
class BaseActivity (line 11) | public class BaseActivity extends AppCompatActivity {
method setProgressBar (line 16) | public void setProgressBar(ProgressBar progressBar) {
method showProgressBar (line 20) | public void showProgressBar() {
method hideProgressBar (line 26) | public void hideProgressBar() {
method hideKeyboard (line 32) | public void hideKeyboard(View view) {
method onStop (line 39) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/BaseFragment.java
class BaseFragment (line 11) | public class BaseFragment extends Fragment {
method setProgressBar (line 16) | public void setProgressBar(ProgressBar progressBar) {
method showProgressBar (line 20) | public void showProgressBar() {
method hideProgressBar (line 26) | public void hideProgressBar() {
method hideKeyboard (line 32) | public void hideKeyboard(View view) {
method onStop (line 40) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/ChooserFragment.java
class ChooserFragment (line 50) | public class ChooserFragment extends Fragment {
method onCreateView (line 93) | @Nullable
method onViewCreated (line 100) | @Override
class MyArrayAdapter (line 118) | public static class MyArrayAdapter extends ArrayAdapter<String> {
method MyArrayAdapter (line 123) | public MyArrayAdapter(Context context, int resource) {
method getView (line 129) | @Override
method setDescriptionIds (line 144) | public void setDescriptionIds(int[] descriptionIds) {
method onDestroyView (line 149) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/CustomAuthFragment.java
class CustomAuthFragment (line 40) | public class CustomAuthFragment extends Fragment {
method onCreateView (line 50) | @Nullable
method onViewCreated (line 57) | @Override
method onStart (line 81) | @Override
method onResume (line 89) | @Override
method onPause (line 96) | @Override
method startSignIn (line 102) | private void startSignIn() {
method updateUI (line 124) | private void updateUI(FirebaseUser user) {
method setCustomToken (line 132) | private void setCustomToken(String token) {
method onDestroyView (line 147) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/EmailPasswordFragment.java
class EmailPasswordFragment (line 41) | public class EmailPasswordFragment extends BaseFragment {
method onCreateView (line 49) | @Nullable
method onViewCreated (line 56) | @Override
method onStart (line 101) | @Override
method createAccount (line 111) | private void createAccount(String email, String password) {
method signIn (line 141) | private void signIn(String email, String password) {
method signOut (line 175) | private void signOut() {
method sendEmailVerification (line 180) | private void sendEmailVerification() {
method reload (line 207) | private void reload() {
method validateForm (line 226) | private boolean validateForm() {
method updateUI (line 248) | private void updateUI(FirebaseUser user) {
method checkForMultiFactorFailure (line 274) | private void checkForMultiFactorFailure(Exception e) {
method onDestroyView (line 288) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/FacebookLoginFragment.java
class FacebookLoginFragment (line 49) | public class FacebookLoginFragment extends BaseFragment {
method onCreateView (line 59) | @Nullable
method onViewCreated (line 66) | @Override
method onStart (line 107) | @Override
method handleFacebookAccessToken (line 115) | private void handleFacebookAccessToken(AccessToken token) {
method signOut (line 142) | public void signOut() {
method updateUI (line 149) | private void updateUI(FirebaseUser user) {
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/FirebaseUIFragment.java
class FirebaseUIFragment (line 33) | public class FirebaseUIFragment extends Fragment {
method onCreateView (line 46) | @Nullable
method onViewCreated (line 53) | @Override
method onDestroyView (line 74) | @Override
method onStart (line 80) | @Override
method onSignInResult (line 86) | private void onSignInResult(FirebaseAuthUIAuthenticationResult result) {
method startSignIn (line 97) | private void startSignIn() {
method updateUI (line 108) | private void updateUI(FirebaseUser user) {
method signOut (line 126) | private void signOut() {
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/GenericIdpFragment.java
class GenericIdpFragment (line 49) | @SuppressWarnings("Convert2Lambda")
method onCreateView (line 68) | @Nullable
method onViewCreated (line 75) | @Override
method onStart (line 113) | @Override
method signIn (line 140) | private void signIn() {
method getProviderId (line 169) | private String getProviderId() {
method updateUI (line 174) | private void updateUI(FirebaseUser user) {
method showToast (line 193) | private void showToast(String message) {
method onDestroyView (line 197) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/GoogleSignInFragment.java
class GoogleSignInFragment (line 53) | public class GoogleSignInFragment extends BaseFragment {
method onCreateView (line 62) | @Nullable
method onViewCreated (line 69) | @Override
method onStart (line 90) | @Override
method signIn (line 98) | private void signIn() {
method showBottomSheet (line 112) | private void showBottomSheet() {
method launchCredentialManager (line 127) | private void launchCredentialManager(GetCredentialRequest request) {
method createGoogleIdToken (line 148) | private void createGoogleIdToken(Credential credential) {
method firebaseAuthWithGoogle (line 166) | private void firebaseAuthWithGoogle(String idToken) {
method signOut (line 186) | private void signOut() {
method updateUI (line 210) | private void updateUI(FirebaseUser user) {
method onDestroyView (line 229) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/MainActivity.java
class MainActivity (line 11) | public class MainActivity extends AppCompatActivity {
method onCreate (line 13) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/MultiFactorEnrollFragment.java
class MultiFactorEnrollFragment (line 34) | public class MultiFactorEnrollFragment extends BaseFragment {
method onCreateView (line 42) | @Nullable
method onViewCreated (line 49) | @Override
method onClickVerifyPhoneNumber (line 70) | private void onClickVerifyPhoneNumber() {
method onClickSignInWithPhoneNumber (line 133) | private void onClickSignInWithPhoneNumber() {
method enrollWithPhoneAuthCredential (line 142) | private void enrollWithPhoneAuthCredential(PhoneAuthCredential credent...
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/MultiFactorFragment.java
class MultiFactorFragment (line 42) | public class MultiFactorFragment extends BaseFragment {
method onCreateView (line 50) | @Nullable
method onViewCreated (line 57) | @Override
method onStart (line 109) | @Override
method signOut (line 117) | private void signOut() {
method sendEmailVerification (line 122) | private void sendEmailVerification() {
method reload (line 149) | private void reload() {
method updateUI (line 168) | private void updateUI(FirebaseUser user) {
method showDisclaimer (line 214) | private void showDisclaimer() {
method onDestroyView (line 224) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/MultiFactorSignInFragment.java
class MultiFactorSignInFragment (line 37) | public class MultiFactorSignInFragment extends BaseFragment {
method onCreateView (line 48) | @Nullable
method onViewCreated (line 55) | @Override
method onSaveInstanceState (line 106) | @Override
method onViewStateRestored (line 112) | @Override
method generateCallbacks (line 120) | private PhoneAuthProvider.OnVerificationStateChangedCallbacks generate...
method getResolverFromArguments (line 144) | private MultiFactorResolver getResolverFromArguments(Bundle arguments) {
method onClickFinishSignIn (line 148) | private void onClickFinishSignIn() {
method onDestroyView (line 179) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/MultiFactorUnenrollFragment.java
class MultiFactorUnenrollFragment (line 24) | public class MultiFactorUnenrollFragment extends BaseFragment {
method onCreateView (line 28) | @Nullable
method onViewCreated (line 35) | @Override
method onDestroyView (line 88) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/PasswordlessActivity.java
class PasswordlessActivity (line 28) | public class PasswordlessActivity extends BaseActivity implements View.O...
method onCreate (line 40) | @Override
method onStart (line 64) | @Override
method onNewIntent (line 70) | @Override
method onSaveInstanceState (line 76) | @Override
method checkIntent (line 87) | private void checkIntent(@Nullable Intent intent) {
method intentHasEmailLink (line 104) | private boolean intentHasEmailLink(@Nullable Intent intent) {
method sendSignInLink (line 118) | private void sendSignInLink(String email) {
method signInWithEmailLink (line 160) | private void signInWithEmailLink(String email, String link) {
method onSendLinkClicked (line 190) | private void onSendLinkClicked() {
method onSignInClicked (line 200) | private void onSignInClicked() {
method onSignOutClicked (line 210) | private void onSignOutClicked() {
method updateUI (line 217) | private void updateUI(@Nullable FirebaseUser user) {
method showSnackbar (line 232) | private void showSnackbar(String message) {
method onClick (line 236) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/PhoneAuthFragment.java
class PhoneAuthFragment (line 31) | public class PhoneAuthFragment extends Fragment {
method onCreateView (line 53) | @Nullable
method onViewCreated (line 60) | @Override
method onStart (line 166) | @Override
method onSaveInstanceState (line 178) | @Override
method onViewStateRestored (line 184) | @Override
method startPhoneNumberVerification (line 192) | private void startPhoneNumberVerification(String phoneNumber) {
method verifyPhoneNumberWithCode (line 205) | private void verifyPhoneNumberWithCode(String verificationId, String c...
method resendVerificationCode (line 210) | private void resendVerificationCode(String phoneNumber,
method signInWithPhoneAuthCredential (line 223) | private void signInWithPhoneAuthCredential(PhoneAuthCredential credent...
method signOut (line 248) | private void signOut() {
method updateUI (line 253) | private void updateUI(int uiState) {
method updateUI (line 257) | private void updateUI(FirebaseUser user) {
method updateUI (line 265) | private void updateUI(int uiState, FirebaseUser user) {
method updateUI (line 269) | private void updateUI(int uiState, PhoneAuthCredential cred) {
method updateUI (line 273) | private void updateUI(int uiState, FirebaseUser user, PhoneAuthCredent...
method validatePhoneNumber (line 338) | private boolean validatePhoneNumber() {
method enableViews (line 348) | private void enableViews(View... views) {
method disableViews (line 354) | private void disableViews(View... views) {
method onDestroyView (line 360) | @Override
FILE: auth/app/src/main/java/com/google/firebase/quickstart/auth/java/TokenBroadcastReceiver.java
class TokenBroadcastReceiver (line 29) | public abstract class TokenBroadcastReceiver extends BroadcastReceiver {
method onReceive (line 36) | @Override
method getFilter (line 46) | public static IntentFilter getFilter() {
method onNewToken (line 51) | public abstract void onNewToken(String token);
FILE: config/app/src/androidTest/java/com/google/samples/quickstart/config/MainActivityTest.java
class MainActivityTest (line 23) | @LargeTest
method testFetchConfig (line 30) | @Test
FILE: config/app/src/main/java/com/google/samples/quickstart/config/java/MainActivity.java
class MainActivity (line 43) | public class MainActivity extends AppCompatActivity {
method onCreate (line 56) | @Override
method fetchWelcome (line 122) | private void fetchWelcome() {
method displayWelcomeMessage (line 151) | private void displayWelcomeMessage() {
FILE: crash/app/src/androidTest/java/com/google/samples/quickstart/crash/MainActivityTest.java
class MainActivityTest (line 23) | @LargeTest
method caughtExceptionTest (line 30) | @Test
FILE: crash/app/src/main/java/com/google/samples/quickstart/crash/java/CustomKeySamples.java
class CustomKeySamples (line 29) | public class CustomKeySamples {
method CustomKeySamples (line 37) | public CustomKeySamples(Context context) {
method setSampleCustomKeys (line 44) | public void setSampleCustomKeys() {
method updateAndTrackNetworkState (line 59) | public void updateAndTrackNetworkState() {
method stopTrackingNetworkState (line 88) | public void stopTrackingNetworkState() {
method updateNetworkCapabilityCustomKeys (line 99) | private void updateNetworkCapabilityCustomKeys(NetworkCapabilities net...
method addPhoneStateRequiredNetworkKeys (line 117) | @Deprecated
method getLocale (line 144) | @SuppressWarnings("deprecation")
method getDensity (line 161) | public float getDensity() {
method getGooglePlayServicesAvailability (line 171) | public String getGooglePlayServicesAvailability() {
method getOsVersion (line 180) | public String getOsVersion() {
method getPreferredAbi (line 191) | @SuppressWarnings("deprecation")
method getInstallSource (line 205) | public String getInstallSource() {
method focusListener (line 237) | public void focusListener(View view, boolean hasFocus) {
FILE: crash/app/src/main/java/com/google/samples/quickstart/crash/java/MainActivity.java
class MainActivity (line 38) | public class MainActivity extends AppCompatActivity {
method onCreate (line 44) | @Override
method onDestroy (line 98) | @Override
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/BaseFragment.java
class BaseFragment (line 10) | public class BaseFragment extends Fragment {
method setProgressBar (line 13) | public void setProgressBar(int resId) {
method showProgressBar (line 17) | public void showProgressBar() {
method hideProgressBar (line 23) | public void hideProgressBar() {
method getUid (line 29) | public String getUid() {
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/MainActivity.java
class MainActivity (line 33) | public class MainActivity extends AppCompatActivity {
method onCreate (line 38) | @Override
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/MainFragment.java
class MainFragment (line 27) | public class MainFragment extends Fragment implements MenuProvider {
method onCreateView (line 33) | @Nullable
method onViewCreated (line 40) | @Override
method onCreateMenu (line 80) | @Override
method onMenuItemSelected (line 85) | @Override
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/NewPostFragment.java
class NewPostFragment (line 28) | public class NewPostFragment extends BaseFragment {
method onCreateView (line 36) | @Nullable
method onViewCreated (line 43) | @Override
method submitPost (line 56) | private void submitPost() {
method setEditingEnabled (line 108) | private void setEditingEnabled(boolean enabled) {
method writeNewPost (line 118) | private void writeNewPost(String userId, String username, String title...
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/PostDetailFragment.java
class PostDetailFragment (line 32) | public class PostDetailFragment extends BaseFragment {
method onCreateView (line 46) | @Nullable
method onViewCreated (line 53) | @Override
method onStart (line 78) | @Override
method onStop (line 111) | @Override
method postComment (line 124) | private void postComment() {
class CommentAdapter (line 152) | private static class CommentAdapter extends RecyclerView.Adapter<Comme...
method CommentAdapter (line 161) | public CommentAdapter(final Context context, DatabaseReference ref) {
method onCreateViewHolder (line 247) | @Override
method onBindViewHolder (line 254) | @Override
method getItemCount (line 261) | @Override
method cleanupListener (line 266) | public void cleanupListener() {
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/SignInFragment.java
class SignInFragment (line 28) | public class SignInFragment extends BaseFragment implements View.OnClick...
method onCreateView (line 37) | @Nullable
method onViewCreated (line 44) | @Override
method onStart (line 58) | @Override
method signIn (line 68) | private void signIn() {
method signUp (line 95) | private void signUp() {
method onAuthSuccess (line 122) | private void onAuthSuccess(FirebaseUser user) {
method usernameFromEmail (line 132) | private String usernameFromEmail(String email) {
method validateForm (line 140) | private boolean validateForm() {
method writeNewUser (line 159) | private void writeNewUser(String userId, String name, String email) {
method onClick (line 165) | public void onClick(View v) {
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/listfragments/MyPostsFragment.java
class MyPostsFragment (line 6) | public class MyPostsFragment extends PostListFragment {
method MyPostsFragment (line 8) | public MyPostsFragment() {}
method getQuery (line 10) | @Override
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/listfragments/MyTopPostsFragment.java
class MyTopPostsFragment (line 6) | public class MyTopPostsFragment extends PostListFragment {
method MyTopPostsFragment (line 8) | public MyTopPostsFragment() {}
method getQuery (line 10) | @Override
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/listfragments/PostListFragment.java
class PostListFragment (line 30) | public abstract class PostListFragment extends Fragment {
method PostListFragment (line 42) | public PostListFragment() {}
method onCreateView (line 44) | @Override
method onActivityCreated (line 60) | @Override
method onStarClicked (line 129) | private void onStarClicked(DatabaseReference postRef) {
method onStart (line 164) | @Override
method onStop (line 172) | @Override
method getUid (line 180) | public String getUid() {
method getQuery (line 184) | public abstract Query getQuery(DatabaseReference databaseReference);
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/listfragments/RecentPostsFragment.java
class RecentPostsFragment (line 6) | public class RecentPostsFragment extends PostListFragment {
method RecentPostsFragment (line 8) | public RecentPostsFragment() {}
method getQuery (line 10) | @Override
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/models/Comment.java
class Comment (line 5) | @IgnoreExtraProperties
method Comment (line 12) | public Comment() {
method Comment (line 16) | public Comment(String uid, String author, String text) {
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/models/Post.java
class Post (line 9) | @IgnoreExtraProperties
method Post (line 19) | public Post() {
method Post (line 23) | public Post(String uid, String author, String title, String body) {
method toMap (line 30) | @Exclude
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/models/User.java
class User (line 5) | @IgnoreExtraProperties
method User (line 11) | public User() {
method User (line 15) | public User(String username, String email) {
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/viewholder/CommentViewHolder.java
class CommentViewHolder (line 10) | public class CommentViewHolder extends RecyclerView.ViewHolder {
method CommentViewHolder (line 14) | public CommentViewHolder(View itemView) {
FILE: database/app/src/main/java/com/google/firebase/quickstart/database/java/viewholder/PostViewHolder.java
class PostViewHolder (line 11) | public class PostViewHolder extends RecyclerView.ViewHolder {
method PostViewHolder (line 19) | public PostViewHolder(View itemView) {
method bindToPost (line 29) | public void bindToPost(Post post, View.OnClickListener starClickListen...
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/FilterDialogFragment.java
class FilterDialogFragment (line 22) | public class FilterDialogFragment extends DialogFragment implements View...
type FilterListener (line 26) | interface FilterListener {
method onFilter (line 28) | void onFilter(Filters filters);
method onCreateView (line 35) | @Nullable
method onDestroyView (line 48) | @Override
method onAttach (line 54) | @Override
method onResume (line 63) | @Override
method onSearchClicked (line 71) | public void onSearchClicked() {
method onCancelClicked (line 79) | public void onCancelClicked() {
method getSelectedCategory (line 83) | @Nullable
method getSelectedCity (line 93) | @Nullable
method getSelectedPrice (line 103) | private int getSelectedPrice() {
method getSelectedSortBy (line 116) | @Nullable
method getSortDirection (line 130) | @Nullable
method resetFilters (line 144) | public void resetFilters() {
method getFilters (line 153) | public Filters getFilters() {
method onClick (line 167) | @Override
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/Filters.java
class Filters (line 14) | public class Filters {
method Filters (line 22) | public Filters() {}
method getDefault (line 24) | public static Filters getDefault() {
method hasCategory (line 32) | public boolean hasCategory() {
method hasCity (line 36) | public boolean hasCity() {
method hasPrice (line 40) | public boolean hasPrice() {
method hasSortBy (line 44) | public boolean hasSortBy() {
method getCategory (line 48) | public String getCategory() {
method setCategory (line 52) | public void setCategory(String category) {
method getCity (line 56) | public String getCity() {
method setCity (line 60) | public void setCity(String city) {
method getPrice (line 64) | public int getPrice() {
method setPrice (line 68) | public void setPrice(int price) {
method getSortBy (line 72) | public String getSortBy() {
method setSortBy (line 76) | public void setSortBy(String sortBy) {
method getSortDirection (line 80) | public Query.Direction getSortDirection() {
method setSortDirection (line 84) | public void setSortDirection(Query.Direction sortDirection) {
method getSearchDescription (line 88) | public String getSearchDescription(Context context) {
method getOrderDescription (line 123) | public String getOrderDescription(Context context) {
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/MainActivity.java
class MainActivity (line 11) | public class MainActivity extends AppCompatActivity {
method onCreate (line 13) | @Override
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/MainFragment.java
class MainFragment (line 56) | public class MainFragment extends Fragment implements
method onCreateView (line 77) | @Nullable
method onViewCreated (line 84) | @Override
method onStart (line 137) | @Override
method onStop (line 156) | @Override
method onCreateMenu (line 164) | @Override
method onMenuItemSelected (line 169) | @Override
method onSignInResult (line 187) | private void onSignInResult(FirebaseAuthUIAuthenticationResult result) {
method onFilterClicked (line 204) | public void onFilterClicked() {
method onClearFilterClicked (line 209) | public void onClearFilterClicked() {
method onRestaurantSelected (line 215) | @Override
method onFilter (line 225) | @Override
method shouldStartSignIn (line 265) | private boolean shouldStartSignIn() {
method startSignIn (line 269) | private void startSignIn() {
method onAddItemsClicked (line 286) | private void onAddItemsClicked() {
method showSignInErrorDialog (line 318) | private void showSignInErrorDialog(@StringRes int message) {
method onClick (line 339) | @Override
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/RatingDialogFragment.java
class RatingDialogFragment (line 23) | public class RatingDialogFragment extends DialogFragment implements View...
type RatingListener (line 29) | interface RatingListener {
method onRating (line 31) | void onRating(Rating rating);
method onCreateView (line 37) | @Nullable
method onDestroyView (line 50) | @Override
method onAttach (line 56) | @Override
method onResume (line 65) | @Override
method onSubmitClicked (line 74) | private void onSubmitClicked(View view) {
method onCancelClicked (line 87) | private void onCancelClicked(View view) {
method onClick (line 91) | @Override
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/RestaurantDetailFragment.java
class RestaurantDetailFragment (line 38) | public class RestaurantDetailFragment extends Fragment
method onCreateView (line 53) | @Nullable
method onViewCreated (line 60) | @Override
method onStart (line 100) | @Override
method onStop (line 108) | @Override
method onEvent (line 123) | @Override
method onRestaurantLoaded (line 133) | private void onRestaurantLoaded(Restaurant restaurant) {
method onBackArrowClicked (line 147) | public void onBackArrowClicked(View view) {
method onAddRatingClicked (line 151) | public void onAddRatingClicked(View view) {
method onRating (line 155) | @Override
method addRating (line 182) | private Task<Void> addRating(final DocumentReference restaurantRef, fi...
method hideKeyboard (line 212) | private void hideKeyboard() {
method onClick (line 220) | @Override
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/adapter/FirestoreAdapter.java
class FirestoreAdapter (line 23) | public abstract class FirestoreAdapter<VH extends RecyclerView.ViewHolder>
method FirestoreAdapter (line 34) | public FirestoreAdapter(Query query) {
method onEvent (line 38) | @Override
method startListening (line 65) | public void startListening() {
method stopListening (line 71) | public void stopListening() {
method setQuery (line 81) | public void setQuery(Query query) {
method getItemCount (line 94) | @Override
method getSnapshot (line 99) | protected DocumentSnapshot getSnapshot(int index) {
method onDocumentAdded (line 103) | protected void onDocumentAdded(DocumentChange change) {
method onDocumentModified (line 108) | protected void onDocumentModified(DocumentChange change) {
method onDocumentRemoved (line 121) | protected void onDocumentRemoved(DocumentChange change) {
method onError (line 126) | protected void onError(FirebaseFirestoreException e) {
method onDataChanged (line 130) | protected void onDataChanged() {}
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/adapter/RatingAdapter.java
class RatingAdapter (line 18) | public class RatingAdapter extends FirestoreAdapter<RatingAdapter.ViewHo...
method RatingAdapter (line 20) | public RatingAdapter(Query query) {
method onCreateViewHolder (line 24) | @Override
method onBindViewHolder (line 30) | @Override
class ViewHolder (line 35) | static class ViewHolder extends RecyclerView.ViewHolder {
method ViewHolder (line 42) | public ViewHolder(ItemRatingBinding binding) {
method bind (line 47) | public void bind(Rating rating) {
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/adapter/RestaurantAdapter.java
class RestaurantAdapter (line 21) | public class RestaurantAdapter extends FirestoreAdapter<RestaurantAdapte...
type OnRestaurantSelectedListener (line 23) | public interface OnRestaurantSelectedListener {
method onRestaurantSelected (line 25) | void onRestaurantSelected(DocumentSnapshot restaurant);
method RestaurantAdapter (line 31) | public RestaurantAdapter(Query query, OnRestaurantSelectedListener lis...
method onCreateViewHolder (line 36) | @Override
method onBindViewHolder (line 42) | @Override
class ViewHolder (line 47) | static class ViewHolder extends RecyclerView.ViewHolder {
method ViewHolder (line 51) | public ViewHolder(ItemRestaurantBinding binding) {
method ViewHolder (line 56) | public ViewHolder(View itemView) {
method bind (line 60) | public void bind(final DocumentSnapshot snapshot,
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/model/Rating.java
class Rating (line 13) | public class Rating {
method Rating (line 21) | public Rating() {}
method Rating (line 23) | public Rating(FirebaseUser user, double rating, String text) {
method getUserId (line 34) | public String getUserId() {
method setUserId (line 38) | public void setUserId(String userId) {
method getUserName (line 42) | public String getUserName() {
method setUserName (line 46) | public void setUserName(String userName) {
method getRating (line 50) | public double getRating() {
method setRating (line 54) | public void setRating(double rating) {
method getText (line 58) | public String getText() {
method setText (line 62) | public void setText(String text) {
method getTimestamp (line 66) | public Date getTimestamp() {
method setTimestamp (line 70) | public void setTimestamp(Date timestamp) {
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/model/Restaurant.java
class Restaurant (line 8) | @IgnoreExtraProperties
method Restaurant (line 25) | public Restaurant() {}
method Restaurant (line 27) | public Restaurant(String name, String city, String category, String ph...
method getName (line 38) | public String getName() {
method setName (line 42) | public void setName(String name) {
method getCity (line 46) | public String getCity() {
method setCity (line 50) | public void setCity(String city) {
method getCategory (line 54) | public String getCategory() {
method setCategory (line 58) | public void setCategory(String category) {
method getPhoto (line 62) | public String getPhoto() {
method setPhoto (line 66) | public void setPhoto(String photo) {
method getPrice (line 70) | public int getPrice() {
method setPrice (line 74) | public void setPrice(int price) {
method getNumRatings (line 78) | public int getNumRatings() {
method setNumRatings (line 82) | public void setNumRatings(int numRatings) {
method getAvgRating (line 86) | public double getAvgRating() {
method setAvgRating (line 90) | public void setAvgRating(double avgRating) {
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/util/RatingUtil.java
class RatingUtil (line 13) | public class RatingUtil {
method getRandomList (line 35) | public static List<Rating> getRandomList(int length) {
method getAverageRating (line 48) | public static double getAverageRating(List<Rating> ratings) {
method getRandom (line 61) | public static Rating getRandom() {
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/util/RestaurantUtil.java
class RestaurantUtil (line 15) | public class RestaurantUtil {
method getRandom (line 47) | public static Restaurant getRandom(Context context) {
method getRandomImageUrl (line 77) | private static String getRandomImageUrl(Random random) {
method getPriceString (line 87) | public static String getPriceString(Restaurant restaurant) {
method getPriceString (line 94) | public static String getPriceString(int priceInt) {
method getRandomName (line 106) | private static String getRandomName(Random random) {
method getRandomString (line 111) | private static String getRandomString(String[] array, Random random) {
method getRandomInt (line 116) | private static int getRandomInt(int[] array, Random random) {
FILE: firestore/app/src/main/java/com/google/firebase/example/fireeats/java/viewmodel/MainActivityViewModel.java
class MainActivityViewModel (line 11) | public class MainActivityViewModel extends ViewModel {
method MainActivityViewModel (line 16) | public MainActivityViewModel() {
method getIsSigningIn (line 21) | public boolean getIsSigningIn() {
method setIsSigningIn (line 25) | public void setIsSigningIn(boolean mIsSigningIn) {
method getFilters (line 29) | public Filters getFilters() {
method setFilters (line 33) | public void setFilters(Filters mFilters) {
FILE: functions/app/src/androidTest/java/com/google/samples/quickstart/functions/MainActivityTest.java
class MainActivityTest (line 16) | @LargeTest
method mainActivityTest (line 23) | @Test
FILE: functions/app/src/androidTest/java/com/google/samples/quickstart/functions/TestAddNumber.java
class TestAddNumber (line 28) | @LargeTest @RunWith(AndroidJUnit4.class)
method setUp (line 33) | @Before public void setUp() {
method testAddNumber (line 37) | @Test
FILE: functions/app/src/main/java/com/google/samples/quickstart/functions/java/FunctionsMessagingService.java
class FunctionsMessagingService (line 20) | public class FunctionsMessagingService extends FirebaseMessagingService {
method FunctionsMessagingService (line 23) | public FunctionsMessagingService() {
method createNotificationChannel (line 26) | private void createNotificationChannel() {
method onMessageReceived (line 40) | @Override
FILE: functions/app/src/main/java/com/google/samples/quickstart/functions/java/MainActivity.java
class MainActivity (line 65) | public class MainActivity extends AppCompatActivity implements View.OnCl...
method onCreate (line 87) | @Override
method addNumbers (line 105) | private Task<Integer> addNumbers(int a, int b) {
method addMessage (line 129) | private Task<String> addMessage(String text) {
method onCalculateClicked (line 151) | private void onCalculateClicked() {
method onAddMessageClicked (line 200) | private void onAddMessageClicked() {
method onSignInClicked (line 237) | private void onSignInClicked() {
method showSnackbar (line 246) | private void showSnackbar(String message) {
method signIn (line 250) | private void signIn() {
method hideKeyboard (line 264) | private void hideKeyboard() {
method onSignInResult (line 272) | private void onSignInResult(FirebaseAuthUIAuthenticationResult result) {
method onClick (line 283) | @Override
method askNotificationPermission (line 299) | private void askNotificationPermission() {
FILE: functions/functions/sanitizer.js
function containsSwearwords (line 40) | function containsSwearwords(message) {
function replaceSwearwords (line 45) | function replaceSwearwords(message) {
function isShouting (line 51) | function isShouting(message) {
function stopShouting (line 57) | function stopShouting(message) {
FILE: inappmessaging/app/src/androidTest/java/com/google/firebase/fiamquickstart/InstrumentedTest.java
class InstrumentedTest (line 36) | @RunWith(AndroidJUnit4.class)
method setUp (line 44) | @Before
method tearDown (line 49) | @After
method testFiamDisplaysOnForegroundCampaign (line 55) | @Test
method testFiamDisplaysContextualTriggerCampaign (line 61) | @Test
method reopen_app (line 67) | private void reopen_app() {
method press_recent (line 72) | private void press_recent() {
method press_back (line 81) | private void press_back() {
method sleep (line 87) | private void sleep() {
method getView (line 95) | @NonNull
FILE: inappmessaging/app/src/main/java/com/google/firebase/fiamquickstart/java/MainActivity.java
class MainActivity (line 17) | public class MainActivity extends AppCompatActivity {
method onCreate (line 24) | @Override
FILE: internal/chooserx/src/main/java/com/firebase/example/internal/BaseEntryChoiceActivity.java
class BaseEntryChoiceActivity (line 11) | public abstract class BaseEntryChoiceActivity extends AppCompatActivity {
method onCreate (line 15) | @Override
method getChoices (line 25) | protected abstract List<Choice> getChoices();
FILE: internal/chooserx/src/main/java/com/firebase/example/internal/Choice.java
class Choice (line 5) | public class Choice {
method Choice (line 11) | public Choice(String title, String description, Intent launchIntent) {
FILE: internal/chooserx/src/main/java/com/firebase/example/internal/ChoiceAdapter.java
class ChoiceAdapter (line 15) | public class ChoiceAdapter extends RecyclerView.Adapter<ChoiceAdapter.Vi...
method ChoiceAdapter (line 20) | public ChoiceAdapter(Activity activity, List<Choice> choices) {
method onCreateViewHolder (line 25) | @NonNull
method onBindViewHolder (line 33) | @Override
method getItemCount (line 39) | @Override
class ViewHolder (line 44) | public class ViewHolder extends RecyclerView.ViewHolder {
method ViewHolder (line 50) | public ViewHolder(View itemView) {
method bind (line 57) | public void bind(final Choice choice) {
FILE: messaging/app/src/androidTest/java/com/google/firebase/quickstart/fcm/MainActivityEspressoTest.java
class MainActivityEspressoTest (line 42) | @RunWith(AndroidJUnit4.class)
method testSubscribeAndLog (line 50) | @Test
method confirmToastStartsWith (line 70) | private void confirmToastStartsWith(String string) {
FILE: messaging/app/src/main/java/com/google/firebase/quickstart/fcm/java/MainActivity.java
class MainActivity (line 41) | public class MainActivity extends AppCompatActivity {
method onCreate (line 55) | @Override
method askNotificationPermission (line 139) | private void askNotificationPermission() {
FILE: messaging/app/src/main/java/com/google/firebase/quickstart/fcm/java/MyFirebaseMessagingService.java
class MyFirebaseMessagingService (line 48) | public class MyFirebaseMessagingService extends FirebaseMessagingService {
method onMessageReceived (line 58) | @Override
method onNewToken (line 119) | @Override
method scheduleJob (line 133) | private void scheduleJob() {
method handleNow (line 144) | private void handleNow() {
method sendRegistrationToServer (line 156) | private void sendRegistrationToServer(String token) {
method sendNotification (line 165) | private void sendNotification(String messageBody) {
FILE: messaging/app/src/main/java/com/google/firebase/quickstart/fcm/java/MyWorker.java
class MyWorker (line 10) | public class MyWorker extends Worker {
method MyWorker (line 14) | public MyWorker(@NonNull Context appContext, @NonNull WorkerParameters...
method doWork (line 18) | @NonNull
FILE: perf/app/src/main/java/com/google/firebase/quickstart/perfmon/java/MainActivity.java
class MainActivity (line 36) | public class MainActivity extends AppCompatActivity {
method onCreate (line 53) | @Override
method loadImageFromWeb (line 112) | private void loadImageFromWeb() {
method writeStringToFile (line 131) | private Task<Void> writeStringToFile(final String filename, final Stri...
method loadStringFromFile (line 150) | private Task<String> loadStringFromFile() {
method loadFileFromDisk (line 183) | private void loadFileFromDisk() {
method getRandomString (line 206) | private String getRandomString(int length) {
FILE: scripts/checksnippets.py
class MissingKotlinFile (line 20) | class MissingKotlinFile(Exception):
method __init__ (line 22) | def __init__(self, javaName):
method __str__ (line 25) | def __str__(self):
class RegionTagMismatch (line 29) | class RegionTagMismatch(Exception):
method __init__ (line 31) | def __init__(self, kotlinName, regionDiff):
method __str__ (line 35) | def __str__(self):
class MissingEndTag (line 40) | class MissingEndTag(Exception):
method __init__ (line 42) | def __init__(self, fileName, missing):
method __str__ (line 46) | def __str__(self):
function checkSnippets (line 51) | def checkSnippets(folder):
function checkJavaFile (line 61) | def checkJavaFile(folder, javaFile):
function regionsInFile (line 87) | def regionsInFile(path):
function findFileWithPattern (line 108) | def findFileWithPattern(folder, pattern):
FILE: storage/app/src/androidTest/java/com/google/firebase/quickstart/firebasestorage/MainActivityTest.java
class MainActivityTest (line 47) | @LargeTest
method grantPermissions (line 58) | @BeforeClass
method before (line 72) | @Before
method after (line 83) | @After
method uploadPhotoTest (line 95) | @Test
method createTempFile (line 143) | private void createTempFile() {
method logOutIfPossible (line 169) | private void logOutIfPossible() {
FILE: storage/app/src/androidTest/java/com/google/firebase/quickstart/firebasestorage/ServiceIdlingResource.java
class ServiceIdlingResource (line 11) | public class ServiceIdlingResource implements IdlingResource {
method ServiceIdlingResource (line 17) | public ServiceIdlingResource(Context context, Class serviceClass) {
method getName (line 22) | @Override
method isIdleNow (line 27) | @Override
method registerIdleTransitionCallback (line 36) | @Override
method isIntentServiceRunning (line 41) | private boolean isIntentServiceRunning() {
FILE: storage/app/src/main/java/com/google/firebase/quickstart/firebasestorage/java/MainActivity.java
class MainActivity (line 57) | public class MainActivity extends AppCompatActivity implements View.OnCl...
method onCreate (line 85) | @Override
method onNewIntent (line 150) | @Override
method onStart (line 161) | @Override
method onStop (line 172) | @Override
method onSaveInstanceState (line 180) | @Override
method uploadFromUri (line 187) | private void uploadFromUri(Uri fileUri) {
method beginDownload (line 207) | private void beginDownload() {
method launchCamera (line 221) | private void launchCamera() {
method signInAnonymously (line 228) | private void signInAnonymously() {
method onUploadResultIntent (line 250) | private void onUploadResultIntent(Intent intent) {
method updateUI (line 258) | private void updateUI(FirebaseUser user) {
method showMessageDialog (line 278) | private void showMessageDialog(String title, String message) {
method showProgressBar (line 286) | private void showProgressBar(String caption) {
method hideProgressBar (line 291) | private void hideProgressBar() {
method askNotificationPermission (line 296) | private void askNotificationPermission() {
method onCreateOptionsMenu (line 309) | @Override
method onOptionsItemSelected (line 315) | @Override
method onClick (line 327) | @Override
FILE: storage/app/src/main/java/com/google/firebase/quickstart/firebasestorage/java/MyBaseTaskService.java
class MyBaseTaskService (line 19) | public abstract class MyBaseTaskService extends Service {
method taskStarted (line 29) | public void taskStarted() {
method taskCompleted (line 33) | public void taskCompleted() {
method changeNumberOfTasks (line 37) | private synchronized void changeNumberOfTasks(int delta) {
method createDefaultChannel (line 48) | private void createDefaultChannel() {
method showProgressNotification (line 63) | protected void showProgressNotification(String caption, long completed...
method showFinishedNotification (line 87) | protected void showFinishedNotification(String caption, Intent intent,...
method dismissProgressNotification (line 112) | protected void dismissProgressNotification() {
FILE: storage/app/src/main/java/com/google/firebase/quickstart/firebasestorage/java/MyDownloadService.java
class MyDownloadService (line 41) | public class MyDownloadService extends MyBaseTaskService {
method onCreate (line 56) | @Override
method onBind (line 64) | @Nullable
method onStartCommand (line 70) | @Override
method downloadFromPath (line 83) | private void downloadFromPath(final String downloadPath) {
method broadcastDownloadFinished (line 144) | private boolean broadcastDownloadFinished(String downloadPath, long by...
method showDownloadFinishedNotification (line 158) | private void showDownloadFinishedNotification(String downloadPath, int...
method getIntentFilter (line 174) | public static IntentFilter getIntentFilter() {
FILE: storage/app/src/main/java/com/google/firebase/quickstart/firebasestorage/java/MyUploadService.java
class MyUploadService (line 27) | public class MyUploadService extends MyBaseTaskService {
method onCreate (line 44) | @Override
method onBind (line 53) | @Nullable
method onStartCommand (line 59) | @Override
method uploadFromUri (line 79) | private void uploadFromUri(final Uri fileUri) {
method broadcastUploadFinished (line 151) | private boolean broadcastUploadFinished(@Nullable Uri downloadUrl, @Nu...
method showUploadFinishedNotification (line 166) | private void showUploadFinishedNotification(@Nullable Uri downloadUrl,...
method getIntentFilter (line 181) | public static IntentFilter getIntentFilter() {
Condensed preview — 658 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,693K chars).
[
{
"path": ".editorconfig",
"chars": 36,
"preview": "[*.{java,kt}]\nmax_line_length = 120\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 592,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: 🐞 Bug in the Firebase SDK\n url: https://github.com/firebase/fire"
},
{
"path": ".github/ISSUE_TEMPLATE/quickstart_issue.md",
"chars": 1162,
"preview": "---\nname: ⚠️ Issue with the quickstart code\nabout:\n Are you having issues running the code in this repository?\n---\n\n<!-"
},
{
"path": ".github/workflows/android.yml",
"chars": 1008,
"preview": "name: Android CI\n\non:\n pull_request:\n push:\n\nconcurrency:\n group: ${{ github.workflow }}-${{ github.event.pull_reques"
},
{
"path": ".gitignore",
"chars": 132,
"preview": ".gradle\nlocal.properties\n.idea\nbuild/\n.DS_Store\n*.iml\n*.apk\n*.aar\n*.zip\ngoogle-services.json\n\n.project\n.settings\n.classp"
},
{
"path": ".google/packaging.yaml",
"chars": 496,
"preview": "# GOOGLE SAMPLE PACKAGING DATA\n#\n# This file is used by Google as part of our samples packaging process.\n# End users may"
},
{
"path": ".opensource/project.json",
"chars": 1033,
"preview": "\n{\n \"name\": \"Firebase Quickstarts for Android\",\n \"parent\": \"quickstarts\",\n \"type\": \"sample\",\n\n \"platforms\": "
},
{
"path": "CONTRIBUTING.md",
"chars": 5704,
"preview": "# Contributing to the Firebase Android Quickstarts\n\nWe'd love for you to contribute to our source code and to make the F"
},
{
"path": "LICENSE",
"chars": 11857,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 2007,
"preview": "# Firebase Quickstarts for Android\n\nA collection of quickstart samples demonstrating the Firebase APIs on Android. For m"
},
{
"path": "admob/.gitignore",
"chars": 94,
"preview": ".gradle\n/local.properties\n.DS_Store\nbuild/\ngoogle-services.json\n\n# Android Studio\n.idea\n*.iml\n"
},
{
"path": "admob/.google/packaging.yaml",
"chars": 1238,
"preview": "# GOOGLE SAMPLE PACKAGING DATA\n#\n# This file is used by Google as part of our samples packaging process.\n# End users may"
},
{
"path": "admob/README.md",
"chars": 1937,
"preview": "AdMob by Google Quickstart\n=======================\n\nThe AdMob by Google Android quickstart demonstrates how to display a"
},
{
"path": "admob/app/build.gradle.kts",
"chars": 2270,
"preview": "import com.android.build.gradle.internal.tasks.factory.dependsOn\n\nplugins {\n alias(libs.plugins.android.application)\n"
},
{
"path": "admob/app/proguard-rules.pro",
"chars": 707,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in ${"
},
{
"path": "admob/app/src/main/AndroidManifest.xml",
"chars": 2248,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:to"
},
{
"path": "admob/app/src/main/java/com/google/samples/quickstart/admobexample/EntryChoiceActivity.kt",
"chars": 804,
"preview": "package com.google.samples.quickstart.admobexample\n\nimport android.content.Intent\nimport com.firebase.example.internal.B"
},
{
"path": "admob/app/src/main/java/com/google/samples/quickstart/admobexample/java/FirstFragment.java",
"chars": 5400,
"preview": "package com.google.samples.quickstart.admobexample.java;\n\nimport android.os.Bundle;\nimport android.util.Log;\nimport andr"
},
{
"path": "admob/app/src/main/java/com/google/samples/quickstart/admobexample/java/MainActivity.java",
"chars": 1168,
"preview": "/**\n * Copyright Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "admob/app/src/main/java/com/google/samples/quickstart/admobexample/java/SecondFragment.java",
"chars": 515,
"preview": "package com.google.samples.quickstart.admobexample.java;\n\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\n"
},
{
"path": "admob/app/src/main/java/com/google/samples/quickstart/admobexample/kotlin/FirstFragment.kt",
"chars": 4819,
"preview": "package com.google.samples.quickstart.admobexample.kotlin\n\nimport android.os.Bundle\nimport android.util.Log\nimport andro"
},
{
"path": "admob/app/src/main/java/com/google/samples/quickstart/admobexample/kotlin/MainActivity.kt",
"chars": 520,
"preview": "package com.google.samples.quickstart.admobexample.kotlin\n\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCom"
},
{
"path": "admob/app/src/main/java/com/google/samples/quickstart/admobexample/kotlin/SecondFragment.kt",
"chars": 503,
"preview": "package com.google.samples.quickstart.admobexample.kotlin\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\ni"
},
{
"path": "admob/app/src/main/res/layout/activity_main.xml",
"chars": 900,
"preview": "<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:"
},
{
"path": "admob/app/src/main/res/layout/fragment_first.xml",
"chars": 1948,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "admob/app/src/main/res/layout/fragment_second.xml",
"chars": 1556,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "admob/app/src/main/res/navigation/nav_graph_java.xml",
"chars": 966,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<navigation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:"
},
{
"path": "admob/app/src/main/res/navigation/nav_graph_kotlin.xml",
"chars": 972,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<navigation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:"
},
{
"path": "admob/app/src/main/res/values/colors.xml",
"chars": 208,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#039BE5</color>\n <color name=\"color"
},
{
"path": "admob/app/src/main/res/values/dimens.xml",
"chars": 211,
"preview": "<resources>\n <!-- Default screen margins, per the Android Design guidelines. -->\n <dimen name=\"activity_horizontal"
},
{
"path": "admob/app/src/main/res/values/strings.xml",
"chars": 774,
"preview": "<resources>\n <string name=\"app_name\">AdMob Quickstart</string>\n <string name=\"hello_world\">Hello world!</string>\n "
},
{
"path": "admob/app/src/main/res/values/styles.xml",
"chars": 348,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.MaterialComponents.Light.Dark"
},
{
"path": "admob/app/src/main/res/values-w820dp/dimens.xml",
"chars": 358,
"preview": "<resources>\n <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n (such as s"
},
{
"path": "admob/build.gradle.kts",
"chars": 376,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nplugins {\n alias"
},
{
"path": "admob/gradle/wrapper/gradle-wrapper.properties",
"chars": 202,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "admob/gradle.properties",
"chars": 755,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "admob/gradlew",
"chars": 8473,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "admob/gradlew.bat",
"chars": 2868,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "admob/settings.gradle.kts",
"chars": 535,
"preview": "pluginManagement {\n repositories {\n google()\n mavenCentral()\n gradlePluginPortal()\n }\n}\n\nincl"
},
{
"path": "analytics/.gitignore",
"chars": 94,
"preview": ".gradle\n/local.properties\n.DS_Store\nbuild/\ngoogle-services.json\n\n# Android Studio\n.idea\n*.iml\n"
},
{
"path": "analytics/README.md",
"chars": 1936,
"preview": "Google Analytics for Firebase Quickstart\n========================================\n\nIntroduction\n------------\n\n- [Read mo"
},
{
"path": "analytics/app/build.gradle.kts",
"chars": 1959,
"preview": "import com.android.build.gradle.internal.tasks.factory.dependsOn\n\nplugins {\n alias(libs.plugins.android.application)\n"
},
{
"path": "analytics/app/proguard-rules.pro",
"chars": 707,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in ${"
},
{
"path": "analytics/app/src/androidTest/java/com/google/firebase/quickstart/analytics/MainActivityTest.java",
"chars": 2743,
"preview": "package com.google.firebase.quickstart.analytics;\n\n\nimport androidx.annotation.StringRes;\nimport androidx.test.espresso."
},
{
"path": "analytics/app/src/main/AndroidManifest.xml",
"chars": 946,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <appli"
},
{
"path": "analytics/app/src/main/java/com/google/firebase/quickstart/analytics/EntryChoiceActivity.kt",
"chars": 924,
"preview": "package com.google.firebase.quickstart.analytics\n\nimport android.content.Intent\nimport com.firebase.example.internal.Bas"
},
{
"path": "analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/ImageFragment.java",
"chars": 2202,
"preview": "/*\n * Copyright Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n "
},
{
"path": "analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/ImageInfo.java",
"chars": 1147,
"preview": "/*\n * Copyright Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n "
},
{
"path": "analytics/app/src/main/java/com/google/firebase/quickstart/analytics/java/MainActivity.java",
"chars": 10779,
"preview": "/*\n * Copyright Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n "
},
{
"path": "analytics/app/src/main/java/com/google/firebase/quickstart/analytics/kotlin/ImageFragment.kt",
"chars": 1501,
"preview": "package com.google.firebase.quickstart.analytics.kotlin\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimp"
},
{
"path": "analytics/app/src/main/java/com/google/firebase/quickstart/analytics/kotlin/ImageInfo.kt",
"chars": 192,
"preview": "package com.google.firebase.quickstart.analytics.kotlin\n\n/**\n * Pair of resource IDs representing an image and its title"
},
{
"path": "analytics/app/src/main/java/com/google/firebase/quickstart/analytics/kotlin/MainActivity.kt",
"chars": 8861,
"preview": "package com.google.firebase.quickstart.analytics.kotlin\n\nimport android.content.Intent\nimport android.os.Bundle\nimport a"
},
{
"path": "analytics/app/src/main/res/drawable/circle.xml",
"chars": 178,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:"
},
{
"path": "analytics/app/src/main/res/layout/activity_main.xml",
"chars": 1635,
"preview": "<!--\nCopyright 2015 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); yo"
},
{
"path": "analytics/app/src/main/res/layout/fragment_main.xml",
"chars": 1629,
"preview": "<!--\nCopyright 2015 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); yo"
},
{
"path": "analytics/app/src/main/res/menu/main.xml",
"chars": 812,
"preview": "<!--\nCopyright 2015 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); yo"
},
{
"path": "analytics/app/src/main/res/values/colors.xml",
"chars": 208,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#039BE5</color>\n <color name=\"color"
},
{
"path": "analytics/app/src/main/res/values/dimens.xml",
"chars": 723,
"preview": "<!--\nCopyright 2015 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); yo"
},
{
"path": "analytics/app/src/main/res/values/strings.xml",
"chars": 1278,
"preview": "<!--\nCopyright 2015 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); yo"
},
{
"path": "analytics/app/src/main/res/values/styles.xml",
"chars": 873,
"preview": "<!--\nCopyright 2015 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); yo"
},
{
"path": "analytics/app/src/main/res/values-v21/styles.xml",
"chars": 940,
"preview": "<!--\nCopyright 2015 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); yo"
},
{
"path": "analytics/app/src/main/res/values-w820dp/dimens.xml",
"chars": 667,
"preview": "<!--\nCopyright 2015 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); yo"
},
{
"path": "analytics/build.gradle.kts",
"chars": 448,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nplugins {\n alias"
},
{
"path": "analytics/gradle/wrapper/gradle-wrapper.properties",
"chars": 202,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "analytics/gradle.properties",
"chars": 754,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "analytics/gradlew",
"chars": 8473,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "analytics/gradlew.bat",
"chars": 2868,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "analytics/settings.gradle.kts",
"chars": 535,
"preview": "pluginManagement {\n repositories {\n google()\n mavenCentral()\n gradlePluginPortal()\n }\n}\n\nincl"
},
{
"path": "appdistribution/.gitignore",
"chars": 93,
"preview": ".gradle\nlocal.properties\n.idea\nbuild/\n.DS_Store\n*.iml\n*.apk\n*.aar\n*.zip\ngoogle-services.json\n"
},
{
"path": "appdistribution/README.md",
"chars": 673,
"preview": "# Firebase App Distribution Quickstart\n\n## Introduction\n\nThe Firebase App Distribution SDK enables you to display in-app"
},
{
"path": "appdistribution/app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "appdistribution/app/build.gradle.kts",
"chars": 2213,
"preview": "\nplugins {\n id(\"com.android.application\")\n id(\"com.google.gms.google-services\")\n}\n\nandroid {\n namespace = \"com."
},
{
"path": "appdistribution/app/proguard-rules.pro",
"chars": 755,
"preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
},
{
"path": "appdistribution/app/src/androidTest/java/com/google/firebase/appdistributionquickstart/InstrumentedTest.java",
"chars": 2689,
"preview": "package com.google.firebase.appdistributionquickstart;\n\nimport android.os.RemoteException;\nimport androidx.annotation.Id"
},
{
"path": "appdistribution/app/src/main/AndroidManifest.xml",
"chars": 1029,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <appli"
},
{
"path": "appdistribution/app/src/main/java/com/google/firebase/appdistributionquickstart/EntryChoiceActivity.kt",
"chars": 887,
"preview": "package com.google.firebase.appdistributionquickstart\n\nimport android.content.Intent\nimport com.firebase.example.interna"
},
{
"path": "appdistribution/app/src/main/java/com/google/firebase/appdistributionquickstart/java/MainActivity.java",
"chars": 1459,
"preview": "package com.google.firebase.appdistributionquickstart.java;\n\nimport android.os.Bundle;\n\nimport androidx.appcompat.app.Ap"
},
{
"path": "appdistribution/app/src/main/java/com/google/firebase/appdistributionquickstart/kotlin/KotlinMainActivity.kt",
"chars": 1452,
"preview": "package com.google.firebase.appdistributionquickstart.kotlin\n\nimport android.os.Bundle\nimport androidx.appcompat.app.App"
},
{
"path": "appdistribution/app/src/main/res/drawable/ic_launcher_background.xml",
"chars": 4867,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector\n android:height=\"108dp\"\n android:width=\"108dp\"\n android:viewport"
},
{
"path": "appdistribution/app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
"chars": 1880,
"preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:aapt=\"http://schemas.android.com/aapt\"\n "
},
{
"path": "appdistribution/app/src/main/res/layout/activity_main.xml",
"chars": 1491,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "appdistribution/app/src/main/res/values/colors.xml",
"chars": 431,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#039BE5</color>\n <color name=\"color"
},
{
"path": "appdistribution/app/src/main/res/values/dimens.xml",
"chars": 67,
"preview": "<resources>\n <dimen name=\"fab_margin\">16dp</dimen>\n</resources>\n"
},
{
"path": "appdistribution/app/src/main/res/values/strings.xml",
"chars": 315,
"preview": "<resources>\n <string name=\"app_name\">App Distribution Quickstart</string>\n <string name=\"textview_text\">Welcome to"
},
{
"path": "appdistribution/app/src/main/res/values/styles.xml",
"chars": 914,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.MaterialComponents.Light.Dark"
},
{
"path": "appdistribution/build.gradle.kts",
"chars": 482,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nplugins {\n alias"
},
{
"path": "appdistribution/gradle/wrapper/gradle-wrapper.properties",
"chars": 202,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "appdistribution/gradle.properties",
"chars": 755,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "appdistribution/gradlew",
"chars": 8473,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "appdistribution/gradlew.bat",
"chars": 2868,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "appdistribution/settings.gradle.kts",
"chars": 535,
"preview": "pluginManagement {\n repositories {\n google()\n mavenCentral()\n gradlePluginPortal()\n }\n}\n\nincl"
},
{
"path": "auth/.gitignore",
"chars": 119,
"preview": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n\nservice_account.json\n"
},
{
"path": "auth/README.md",
"chars": 7994,
"preview": "Firebase Auth Quickstart\n==============================\n\nIntroduction\n------------\n\n- [Read more about Firebase Auth](ht"
},
{
"path": "auth/app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "auth/app/build.gradle.kts",
"chars": 2678,
"preview": "import com.android.build.gradle.internal.tasks.factory.dependsOn\n\nplugins {\n alias(libs.plugins.android.application)\n"
},
{
"path": "auth/app/proguard-rules.pro",
"chars": 1212,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in ${"
},
{
"path": "auth/app/src/main/AndroidManifest.xml",
"chars": 2851,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:to"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/EntryChoiceActivity.kt",
"chars": 781,
"preview": "package com.google.firebase.quickstart.auth\n\nimport android.content.Intent\nimport com.firebase.example.internal.BaseEntr"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/AnonymousAuthFragment.java",
"chars": 7409,
"preview": "/**\n * Copyright 2021 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/BaseActivity.java",
"chars": 1160,
"preview": "package com.google.firebase.quickstart.auth.java;\n\nimport android.content.Context;\nimport android.view.View;\nimport andr"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/BaseFragment.java",
"chars": 1176,
"preview": "package com.google.firebase.quickstart.auth.java;\n\nimport android.content.Context;\nimport android.view.View;\nimport andr"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/ChooserFragment.java",
"chars": 5396,
"preview": "/**\n * Copyright 2021 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/CustomAuthFragment.java",
"chars": 5268,
"preview": "/**\n * Copyright Google Inc. All Rights Reserved.\n * <p/>\n * Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/EmailPasswordFragment.java",
"chars": 11416,
"preview": "/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n * <p>\n * Licensed under the Apache License, Version 2.0 (the \"Li"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/FacebookLoginFragment.java",
"chars": 6100,
"preview": "/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/FirebaseUIFragment.java",
"chars": 4422,
"preview": "package com.google.firebase.quickstart.auth.java;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport an"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/GenericIdpFragment.java",
"chars": 7594,
"preview": "/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/GoogleSignInFragment.java",
"chars": 9650,
"preview": "/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/MainActivity.java",
"chars": 611,
"preview": "package com.google.firebase.quickstart.auth.java;\n\nimport android.os.Bundle;\n\nimport androidx.annotation.Nullable;\nimpor"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/MultiFactorEnrollFragment.java",
"chars": 7569,
"preview": "package com.google.firebase.quickstart.auth.java;\n\nimport android.os.Bundle;\nimport android.text.TextUtils;\nimport andro"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/MultiFactorFragment.java",
"chars": 8690,
"preview": "/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n * <p>\n * Licensed under the Apache License, Version 2.0 (the \"Li"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/MultiFactorSignInFragment.java",
"chars": 7607,
"preview": "package com.google.firebase.quickstart.auth.java;\n\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport "
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/MultiFactorUnenrollFragment.java",
"chars": 4041,
"preview": "package com.google.firebase.quickstart.auth.java;\n\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport "
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/PasswordlessActivity.java",
"chars": 9081,
"preview": "package com.google.firebase.quickstart.auth.java;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport andro"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/PhoneAuthFragment.java",
"chars": 15227,
"preview": "package com.google.firebase.quickstart.auth.java;\n\nimport android.os.Bundle;\nimport android.text.TextUtils;\nimport andro"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/java/TokenBroadcastReceiver.java",
"chars": 1759,
"preview": "/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/AnonymousAuthFragment.kt",
"chars": 5559,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.os.Bundle\nimport android.text.TextUtils\nimport androi"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/BaseActivity.kt",
"chars": 861,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.content.Context\nimport android.view.View\nimport andro"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/BaseFragment.kt",
"chars": 853,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.content.Context\nimport android.view.View\nimport andro"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/ChooserFragment.kt",
"chars": 4376,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.content.Context\nimport android.os.Bundle\nimport andro"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/CustomAuthFragment.kt",
"chars": 4117,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.os.Bundle\nimport android.util.Log\nimport android.view"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/EmailPasswordFragment.kt",
"chars": 8786,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.os.Bundle\nimport android.text.TextUtils\nimport androi"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/FacebookLoginFragment.kt",
"chars": 4843,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.os.Bundle\nimport android.util.Log\nimport android.view"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/FirebaseUIFragment.kt",
"chars": 3816,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.app.Activity\nimport android.os.Bundle\nimport android."
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/GenericIdpFragment.kt",
"chars": 6015,
"preview": "/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/GoogleSignInFragment.kt",
"chars": 7685,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.os.Bundle\nimport android.util.Log\nimport android.view"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/MainActivity.kt",
"chars": 506,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCompatActi"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/MultiFactorEnrollFragment.kt",
"chars": 5470,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.os.Bundle\nimport android.text.TextUtils\nimport androi"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/MultiFactorFragment.kt",
"chars": 6284,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.app.AlertDialog\nimport android.os.Bundle\nimport andro"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/MultiFactorSignInFragment.kt",
"chars": 6082,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.os.Bundle\nimport android.text.TextUtils\nimport androi"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/MultiFactorUnenrollFragment.kt",
"chars": 3100,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport a"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/PasswordlessActivity.kt",
"chars": 7617,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.content.Intent\nimport android.os.Bundle\nimport androi"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/PhoneAuthFragment.kt",
"chars": 13857,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.os.Bundle\nimport android.text.TextUtils\nimport androi"
},
{
"path": "auth/app/src/main/java/com/google/firebase/quickstart/auth/kotlin/TokenBroadcastReceiver.kt",
"chars": 1025,
"preview": "package com.google.firebase.quickstart.auth.kotlin\n\nimport android.content.BroadcastReceiver\nimport android.content.Cont"
},
{
"path": "auth/app/src/main/res/layout/activity_main.xml",
"chars": 937,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
},
{
"path": "auth/app/src/main/res/layout/activity_passwordless.xml",
"chars": 5350,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/r"
},
{
"path": "auth/app/src/main/res/layout/fragment_anonymous_auth.xml",
"chars": 7717,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/r"
},
{
"path": "auth/app/src/main/res/layout/fragment_chooser.xml",
"chars": 350,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andro"
},
{
"path": "auth/app/src/main/res/layout/fragment_custom.xml",
"chars": 2099,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmln"
},
{
"path": "auth/app/src/main/res/layout/fragment_emailpassword.xml",
"chars": 7558,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/too"
},
{
"path": "auth/app/src/main/res/layout/fragment_facebook.xml",
"chars": 2713,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmln"
},
{
"path": "auth/app/src/main/res/layout/fragment_firebase_ui.xml",
"chars": 2540,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/too"
},
{
"path": "auth/app/src/main/res/layout/fragment_generic_idp.xml",
"chars": 4918,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmln"
},
{
"path": "auth/app/src/main/res/layout/fragment_google.xml",
"chars": 3182,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/r"
},
{
"path": "auth/app/src/main/res/layout/fragment_multi_factor.xml",
"chars": 6917,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/too"
},
{
"path": "auth/app/src/main/res/layout/fragment_multi_factor_sign_in.xml",
"chars": 2055,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andr"
},
{
"path": "auth/app/src/main/res/layout/fragment_passwordless.xml",
"chars": 5350,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"http://schemas.android.com/apk/r"
},
{
"path": "auth/app/src/main/res/layout/fragment_phone_auth.xml",
"chars": 6202,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/too"
},
{
"path": "auth/app/src/main/res/layout/item_spinner_list.xml",
"chars": 395,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:to"
},
{
"path": "auth/app/src/main/res/navigation/nav_graph_java.xml",
"chars": 5153,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<navigation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:"
},
{
"path": "auth/app/src/main/res/navigation/nav_graph_kotlin.xml",
"chars": 5183,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<navigation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:"
},
{
"path": "auth/app/src/main/res/values/colors.xml",
"chars": 338,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#039BE5</color>\n <color name=\"color"
},
{
"path": "auth/app/src/main/res/values/dimens.xml",
"chars": 469,
"preview": "<resources>\n <!-- Default screen margins, per the Android Design guidelines. -->\n <dimen name=\"activity_horizontal"
},
{
"path": "auth/app/src/main/res/values/ids.xml",
"chars": 279,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n <!--\n Your Facebook App ID. See README.\n -->\n <!-- "
},
{
"path": "auth/app/src/main/res/values/strings.xml",
"chars": 5876,
"preview": "<resources>\n <string name=\"app_name\">Firebase Authentication</string>\n\n <string name=\"label_google_sign_in\">Fireba"
},
{
"path": "auth/app/src/main/res/values/styles.xml",
"chars": 2028,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.MaterialComponents.Light.Dark"
},
{
"path": "auth/app/src/main/res/values-land/dimens.xml",
"chars": 159,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <dimen name=\"icon_top_margin\">0dp</dimen>\n <dimen name=\"icon_b"
},
{
"path": "auth/app/src/main/res/values-v21/styles.xml",
"chars": 327,
"preview": "<resources>\n\n <style name=\"AppTheme.NoActionBar\">\n <item name=\"windowActionBar\">false</item>\n <item nam"
},
{
"path": "auth/app/src/main/res/values-w820dp/dimens.xml",
"chars": 358,
"preview": "<resources>\n <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n (such as s"
},
{
"path": "auth/build.gradle.kts",
"chars": 482,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nplugins {\n alias"
},
{
"path": "auth/gradle/wrapper/gradle-wrapper.properties",
"chars": 202,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "auth/gradle.properties",
"chars": 755,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "auth/gradlew",
"chars": 8473,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "auth/gradlew.bat",
"chars": 2868,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "auth/settings.gradle.kts",
"chars": 535,
"preview": "pluginManagement {\n repositories {\n google()\n mavenCentral()\n gradlePluginPortal()\n }\n}\n\nincl"
},
{
"path": "auth/web/auth.html",
"chars": 5293,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=utf-8 />\n <meta name=\"viewport\" content=\"width=device-width, initial-scal"
},
{
"path": "build.gradle.kts",
"chars": 2617,
"preview": "import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask\n\nplugins {\n alias(libs.plugins.android.appli"
},
{
"path": "build_pull_request.sh",
"chars": 839,
"preview": "#!/bin/bash\n\n# Exit on error\nset -e\n\n# unshallow since GitHub actions does a shallow clone\ngit fetch --unshallow\ngit fet"
},
{
"path": "config/README.md",
"chars": 5215,
"preview": "Firebase Remote Config Quickstart\n==============================\n\nThe Firebase Remote Config Android quickstart app demo"
},
{
"path": "config/app/build.gradle.kts",
"chars": 1903,
"preview": "import com.android.build.gradle.internal.tasks.factory.dependsOn\n\nplugins {\n alias(libs.plugins.android.application)\n"
},
{
"path": "config/app/proguard-rules.pro",
"chars": 707,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in ${"
},
{
"path": "config/app/src/androidTest/java/com/google/samples/quickstart/config/MainActivityTest.java",
"chars": 1519,
"preview": "package com.google.samples.quickstart.config;\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\nimport androidx.tes"
},
{
"path": "config/app/src/main/AndroidManifest.xml",
"chars": 921,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n <appli"
},
{
"path": "config/app/src/main/java/com/google/samples/quickstart/config/EntryChoiceActivity.kt",
"chars": 920,
"preview": "package com.google.samples.quickstart.config\n\nimport android.content.Intent\nimport com.firebase.example.internal.BaseEnt"
},
{
"path": "config/app/src/main/java/com/google/samples/quickstart/config/java/MainActivity.java",
"chars": 6725,
"preview": "/*\n * Copyright Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n "
},
{
"path": "config/app/src/main/java/com/google/samples/quickstart/config/kotlin/MainActivity.kt",
"chars": 5010,
"preview": "package com.google.samples.quickstart.config.kotlin\n\nimport android.os.Bundle\nimport android.util.Log\nimport android.wid"
},
{
"path": "config/app/src/main/res/layout/activity_main.xml",
"chars": 1835,
"preview": "<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:"
},
{
"path": "config/app/src/main/res/values/colors.xml",
"chars": 208,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#039BE5</color>\n <color name=\"color"
},
{
"path": "config/app/src/main/res/values/dimens.xml",
"chars": 211,
"preview": "<resources>\n <!-- Default screen margins, per the Android Design guidelines. -->\n <dimen name=\"activity_horizontal"
},
{
"path": "config/app/src/main/res/values/strings.xml",
"chars": 163,
"preview": "<resources>\n <string name=\"app_name\">Firebase Remote Config</string>\n <string name=\"fetch_remote_welcome_message\">"
},
{
"path": "config/app/src/main/res/values/styles.xml",
"chars": 348,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.MaterialComponents.Light.Dark"
},
{
"path": "config/app/src/main/res/values-w820dp/dimens.xml",
"chars": 358,
"preview": "<resources>\n <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n (such as s"
},
{
"path": "config/app/src/main/res/xml/remote_config_defaults.xml",
"chars": 429,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- START xml_defaults -->\n<defaultsMap>\n <entry>\n <key>loading_phrase"
},
{
"path": "config/build.gradle.kts",
"chars": 376,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nplugins {\n alias"
},
{
"path": "config/gradle/wrapper/gradle-wrapper.properties",
"chars": 202,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
},
{
"path": "config/gradle.properties",
"chars": 755,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "config/gradlew",
"chars": 8473,
"preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "config/gradlew.bat",
"chars": 2868,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "config/settings.gradle.kts",
"chars": 535,
"preview": "pluginManagement {\n repositories {\n google()\n mavenCentral()\n gradlePluginPortal()\n }\n}\n\nincl"
},
{
"path": "copy_mock_google_services_json.sh",
"chars": 1060,
"preview": "#!/bin/bash\n\n# Exit on error\nset -e\n\n# Copy mock google-services file\necho \"Using mock google-services.json\"\ncp mock-goo"
},
{
"path": "crash/.gitignore",
"chars": 118,
"preview": "*.iml\ngoogle-services.json\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n"
},
{
"path": "crash/README.md",
"chars": 1387,
"preview": "Firebase Crashlytics Quickstart\n===============================\n\nIntroduction\n------------\n\n- [Read more about Firebase "
},
{
"path": "crash/app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "crash/app/build.gradle.kts",
"chars": 2496,
"preview": "import com.android.build.gradle.internal.tasks.factory.dependsOn\n\nplugins {\n alias(libs.plugins.android.application)\n"
},
{
"path": "crash/app/proguard-rules.pro",
"chars": 844,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in ${"
},
{
"path": "crash/app/src/androidTest/java/com/google/samples/quickstart/crash/MainActivityTest.java",
"chars": 1784,
"preview": "package com.google.samples.quickstart.crash;\n\n\nimport androidx.test.espresso.ViewInteraction;\nimport androidx.test.ext.j"
},
{
"path": "crash/app/src/main/AndroidManifest.xml",
"chars": 1438,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\nCopyright Google Inc. All rights reserved.\nLicensed under the Apache License"
},
{
"path": "crash/app/src/main/java/com/google/samples/quickstart/crash/EntryChoiceActivity.kt",
"chars": 783,
"preview": "package com.google.samples.quickstart.crash\n\nimport android.content.Intent\nimport com.firebase.example.internal.BaseEntr"
},
{
"path": "crash/app/src/main/java/com/google/samples/quickstart/crash/java/CustomKeySamples.java",
"chars": 9511,
"preview": "package com.google.samples.quickstart.crash.java;\n\nimport android.Manifest;\nimport android.annotation.SuppressLint;\nimpo"
},
{
"path": "crash/app/src/main/java/com/google/samples/quickstart/crash/java/MainActivity.java",
"chars": 4010,
"preview": "/*\n * Copyright Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n "
}
]
// ... and 458 more files (download for full content)
About this extraction
This page contains the full source code of the firebase/quickstart-android GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 658 files (1.5 MB), approximately 366.6k tokens, and a symbol index with 613 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.