From 40158ead05fa1a9e8c2a086e042c3df39f4c09e8 Mon Sep 17 00:00:00 2001 From: Ademola Fadumo Date: Mon, 10 Nov 2025 17:06:21 +0100 Subject: [PATCH 01/11] repository clean up --- {composeapp => app}/.gitignore | 0 app/build.gradle.kts | 112 +- {composeapp => app}/proguard-rules.pro | 0 app/src/main/AndroidManifest.xml | 87 +- .../src/main/ic_launcher-playstore.png | Bin .../AuthFlowControllerDemoActivity.kt | 4 +- .../CustomSlotsThemingDemoActivity.kt | 8 +- .../composeapp/HighLevelApiDemoActivity.kt | 4 +- .../com/firebase/composeapp/MainActivity.kt | 2 +- .../com/firebase/composeapp/ui/theme/Color.kt | 2 +- .../com/firebase/composeapp/ui/theme/Theme.kt | 2 +- .../com/firebase/composeapp/ui/theme/Type.kt | 2 +- .../com/firebase/uidemo/ChooserActivity.java | 140 -- .../com/firebase/uidemo/FirebaseUIDemo.java | 10 - .../uidemo/auth/AnonymousUpgradeActivity.java | 192 --- .../firebase/uidemo/auth/AuthUiActivity.java | 438 ----- .../uidemo/auth/SignedInActivity.java | 212 --- .../uidemo/database/AbstractChat.java | 32 - .../firebase/uidemo/database/ChatHolder.java | 80 - .../uidemo/database/firestore/Chat.java | 104 -- .../firestore/FirestoreChatActivity.java | 168 -- .../firestore/FirestorePagingActivity.java | 200 --- .../uidemo/database/realtime/Chat.java | 84 - .../realtime/FirebaseDbPagingActivity.java | 197 --- .../realtime/RealtimeDbChatActivity.java | 156 -- .../realtime/RealtimeDbChatIndexActivity.java | 62 - .../uidemo/storage/ImageActivity.java | 160 -- .../uidemo/storage/MyAppGlideModule.java | 32 - .../uidemo/util/ConfigurationUtils.java | 64 - .../uidemo/util/SignInResultNotifier.java | 31 - .../main/res/drawable-hdpi/firebase_auth.png | Bin .../res/drawable-hdpi/firebase_auth_120dp.png | Bin 14632 -> 0 bytes .../main/res/drawable-mdpi/firebase_auth.png | Bin .../res/drawable-mdpi/firebase_auth_120dp.png | Bin 7189 -> 0 bytes .../drawable-v24/ic_launcher_foreground.xml | 0 .../main/res/drawable-xhdpi/firebase_auth.png | Bin .../drawable-xhdpi/firebase_auth_120dp.png | Bin 15823 -> 0 bytes .../res/drawable-xxhdpi/firebase_auth.png | Bin .../drawable-xxhdpi/firebase_auth_120dp.png | Bin 31998 -> 0 bytes .../res/drawable-xxxhdpi/firebase_auth.png | Bin .../drawable-xxxhdpi/firebase_auth_120dp.png | Bin 35146 -> 0 bytes .../main/res/drawable/custom_bg_gradient.xml | 7 - .../main/res/drawable/ic_anon_user_48dp.xml | 31 - .../res/drawable/ic_chat_message_arrow.xml | 15 - .../drawable/ic_chat_message_background.xml | 7 - .../src/main/res/drawable/ic_discord_24dp.xml | 0 .../res/drawable/ic_googleg_color_144dp.xml | 19 - .../res/drawable/ic_launcher_background.xml | 0 .../main/res/drawable/ic_line_logo_24dp.xml | 0 .../auth_method_picker_custom_layout.xml | 190 --- .../res/layout/activity_anonymous_upgrade.xml | 67 - app/src/main/res/layout/activity_chat.xml | 61 - app/src/main/res/layout/activity_chooser.xml | 17 - .../main/res/layout/activity_chooser_item.xml | 39 - .../res/layout/activity_database_paging.xml | 21 - .../res/layout/activity_firestore_paging.xml | 21 - app/src/main/res/layout/activity_image.xml | 57 - .../auth_method_picker_custom_layout.xml | 160 -- app/src/main/res/layout/auth_ui_layout.xml | 340 ---- app/src/main/res/layout/item_item.xml | 32 - app/src/main/res/layout/message.xml | 62 - app/src/main/res/layout/signed_in_layout.xml | 158 -- app/src/main/res/menu/menu_paging.xml | 11 - .../res/mipmap-anydpi-v26/ic_launcher.xml | 4 +- .../mipmap-anydpi-v26/ic_launcher_round.xml | 4 +- app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 1772 -> 0 bytes .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin .../mipmap-hdpi/ic_launcher_foreground.png | Bin 2403 -> 0 bytes .../mipmap-hdpi/ic_launcher_foreground.webp | Bin .../res/mipmap-hdpi/ic_launcher_round.png | Bin 3646 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 1212 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin .../mipmap-mdpi/ic_launcher_foreground.png | Bin 1361 -> 0 bytes .../mipmap-mdpi/ic_launcher_foreground.webp | Bin .../res/mipmap-mdpi/ic_launcher_round.png | Bin 2267 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 2366 -> 0 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 3062 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.webp | Bin .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 5155 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 3861 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 6178 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.webp | Bin .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 8391 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 5349 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 7609 -> 0 bytes .../ic_launcher_foreground.webp | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 11866 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin app/src/main/res/values-w820dp/dimens.xml | 6 - app/src/main/res/values/colors.xml | 26 +- app/src/main/res/values/config.xml | 11 - app/src/main/res/values/dimens.xml | 5 - .../res/values/ic_launcher_background.xml | 0 app/src/main/res/values/strings.xml | 133 +- app/src/main/res/values/styles.xml | 46 - .../src/main/res/values/themes.xml | 0 app/src/main/res/xml-v25/shortcuts.xml | 46 - auth/src/main/AndroidManifest.xml | 81 +- .../ui/auth/{compose => }/AuthException.kt | 0 .../auth/{compose => }/AuthFlowController.kt | 0 .../ui/auth/AuthMethodPickerLayout.java | 211 --- .../ui/auth/{compose => }/AuthState.kt | 1 - .../java/com/firebase/ui/auth/AuthUI.java | 1429 ----------------- .../java/com/firebase/ui/auth/ErrorCodes.java | 144 -- .../{compose => }/FirebaseAuthActivity.kt | 3 - ...FirebaseAuthAnonymousUpgradeException.java | 21 - .../ui/auth/{compose => }/FirebaseAuthUI.kt | 4 +- .../FirebaseAuthUIActivityResultContract.java | 34 - .../FirebaseUIComposeRegistrar.kt | 0 .../firebase/ui/auth/FirebaseUiException.java | 44 - .../FirebaseUiUserCollisionException.java | 55 - .../com/firebase/ui/auth/IdpResponse.java | 401 ----- .../com/firebase/ui/auth/KickoffActivity.java | 94 -- .../configuration/AuthUIConfiguration.kt | 0 .../configuration/MfaConfiguration.kt | 0 .../{compose => }/configuration/MfaFactor.kt | 0 .../configuration/PasswordRule.kt | 0 .../AnonymousAuthProvider+FirebaseAuthUI.kt | 0 .../auth_provider/AuthProvider.kt | 11 +- .../EmailAuthProvider+FirebaseAuthUI.kt | 4 +- .../FacebookAuthProvider+FirebaseAuthUI.kt | 0 .../GoogleAuthProvider+FirebaseAuthUI.kt | 0 .../OAuthProvider+FirebaseAuthUI.kt | 0 .../PhoneAuthProvider+FirebaseAuthUI.kt | 0 .../string_provider/AuthUIStringProvider.kt | 0 .../AuthUIStringProviderSample.kt | 0 .../DefaultAuthUIStringProvider.kt | 0 .../configuration/theme/AuthUIAsset.kt | 0 .../configuration/theme/AuthUITheme.kt | 0 .../theme/ProviderStyleDefaults.kt | 0 .../validators/EmailValidator.kt | 0 .../validators/FieldValidationStatus.kt | 0 .../validators/FieldValidator.kt | 0 .../validators/GeneralFieldValidator.kt | 0 .../validators/PasswordValidator.kt | 0 .../validators/PhoneNumberValidator.kt | 0 .../validators/VerificationCodeValidator.kt | 0 .../credentialmanager/PasswordCredential.kt | 0 .../PasswordCredentialHandler.kt | 0 .../ui/auth/{compose => }/data/Countries.kt | 0 .../ui/auth/{compose => }/data/CountryData.kt | 0 .../auth/data/client/AuthUiInitProvider.java | 62 - .../ui/auth/data/model/CountryInfo.java | 130 -- .../FirebaseAuthUIAuthenticationResult.java | 57 - .../ui/auth/data/model/FlowParameters.java | 223 --- .../data/model/IntentRequiredException.java | 30 - .../model/PendingIntentRequiredException.java | 65 - .../ui/auth/data/model/PhoneNumber.java | 80 - ...neNumberVerificationRequiredException.java | 32 - .../firebase/ui/auth/data/model/Resource.java | 100 -- .../firebase/ui/auth/data/model/State.java | 8 - .../com/firebase/ui/auth/data/model/User.java | 165 -- .../data/model/UserCancellationException.java | 13 - .../data/remote/AnonymousSignInHandler.java | 71 - .../auth/data/remote/EmailSignInHandler.java | 51 - .../data/remote/FacebookSignInHandler.java | 167 -- ...ericIdpAnonymousUpgradeLinkingHandler.java | 62 - .../data/remote/GenericIdpSignInHandler.java | 293 ---- .../auth/data/remote/GoogleSignInHandler.java | 132 -- .../auth/data/remote/PhoneSignInHandler.java | 48 - .../ui/auth/data/remote/ProfileMerger.java | 57 - .../ui/auth/data/remote/SignInKickstarter.kt | 247 --- .../remote/SingleProviderSignInHandler.java | 25 - .../mfa/MfaChallengeContentState.kt | 0 .../mfa/MfaEnrollmentContentState.kt | 0 .../{compose => }/mfa/MfaEnrollmentStep.kt | 0 .../auth/{compose => }/mfa/MfaErrorMapper.kt | 0 .../{compose => }/mfa/SmsEnrollmentHandler.kt | 0 .../mfa/TotpEnrollmentHandler.kt | 0 .../ui/auth/{compose => }/mfa/TotpSecret.kt | 0 .../com/firebase/ui/auth/package-info.java | 2 +- .../firebase/ui/auth/ui/AppCompatBase.java | 67 - .../com/firebase/ui/auth/ui/FragmentBase.java | 38 - .../ui/auth/ui/HelperActivityBase.java | 111 -- .../ui/auth/ui/InvisibleActivityBase.java | 96 -- .../ui/auth/ui/InvisibleFragmentBase.java | 88 - .../com/firebase/ui/auth/ui/ProgressView.java | 16 - .../ui/components/AuthProviderButton.kt | 0 .../ui/components/AuthTextField.kt | 0 .../ui/components/CountrySelector.kt | 2 +- .../ui/components/ErrorRecoveryDialog.kt | 0 .../ui/components/QrCodeImage.kt | 0 .../ui/components/ReauthenticationDialog.kt | 0 .../ui/components/TermsAndPrivacyForm.kt | 0 .../ui/components/TopLevelDialogController.kt | 0 .../components/VerificationCodeInputField.kt | 0 .../ui/credentials/CredentialSaveActivity.kt | 86 - .../ui/auth/ui/email/CheckEmailFragment.java | 238 --- .../ui/auth/ui/email/CheckEmailHandler.java | 108 -- .../ui/auth/ui/email/EmailActivity.java | 247 --- .../ui/email/EmailLinkCatcherActivity.java | 140 -- .../EmailLinkCrossDeviceLinkingFragment.java | 123 -- .../email/EmailLinkErrorRecoveryActivity.java | 79 - .../ui/auth/ui/email/EmailLinkFragment.java | 174 -- .../email/EmailLinkPromptEmailFragment.java | 148 -- .../ui/email/RecoverPasswordActivity.java | 154 -- .../auth/ui/email/RegisterEmailFragment.java | 288 ---- .../ui/email/TroubleSigningInFragment.java | 99 -- .../ui/email/WelcomeBackEmailLinkPrompt.java | 118 -- .../ui/email/WelcomeBackPasswordPrompt.java | 207 --- .../ui/auth/ui/email/package-info.java | 18 - .../auth/ui/idp/AuthMethodPickerActivity.kt | 492 ------ .../ui/auth/ui/idp/SingleSignInActivity.java | 146 -- .../ui/auth/ui/idp/WelcomeBackIdpPrompt.java | 220 --- .../firebase/ui/auth/ui/idp/package-info.java | 18 - .../method_picker/AnnotatedStringResource.kt | 0 .../ui/method_picker/AuthMethodPicker.kt | 0 .../com/firebase/ui/auth/ui/package-info.java | 18 - .../ui/auth/ui/phone/CheckPhoneHandler.java | 92 -- .../ui/phone/CheckPhoneNumberFragment.java | 240 --- .../ui/auth/ui/phone/CountryListSpinner.java | 290 ---- .../ui/auth/ui/phone/PhoneActivity.java | 246 --- .../phone/PhoneNumberVerificationHandler.java | 91 -- .../ui/auth/ui/phone/PhoneVerification.java | 63 - .../ui/auth/ui/phone/SpacedEditText.java | 121 -- .../phone/SubmitConfirmationCodeFragment.java | 246 --- .../ui/screens/FirebaseAuthScreen.kt | 1 + .../ui/screens/MfaChallengeDefaults.kt | 0 .../ui/screens/MfaChallengeScreen.kt | 0 .../ui/screens/MfaEnrollmentDefaults.kt | 0 .../ui/screens/MfaEnrollmentScreen.kt | 2 +- .../ui/screens/email/EmailAuthScreen.kt | 2 +- .../ui/screens/email/ResetPasswordUI.kt | 2 +- .../ui/screens/email/SignInEmailLinkUI.kt | 2 +- .../ui/screens/email/SignInUI.kt | 2 +- .../ui/screens/email/SignUpUI.kt | 2 +- .../ui/screens/phone/EnterPhoneNumberUI.kt | 7 +- .../screens/phone/EnterVerificationCodeUI.kt | 0 .../ui/screens/phone/PhoneAuthScreen.kt | 2 +- .../ui/auth/util/ContinueUrlBuilder.kt | 72 + .../{compose/data => util}/CountryUtils.kt | 20 +- .../ui/auth/util/CredentialUtils.java | 107 -- .../{compose => }/util/EmailLinkConstants.kt | 0 .../firebase/ui/auth/util/EmailLinkParser.kt | 99 ++ .../util/EmailLinkPersistenceManager.kt | 0 .../firebase/ui/auth/util/ExtraConstants.java | 61 - .../ui/auth/util/FirebaseAuthError.java | 111 -- .../firebase/ui/auth/util/GoogleApiUtils.java | 34 - .../{compose => }/util/PersistenceManager.kt | 0 .../firebase/ui/auth/util/PhoneNumberUtils.kt | 72 + .../firebase/ui/auth/util/Preconditions.java | 4 +- .../ui/auth/util/ProviderAvailability.kt | 38 + .../com/firebase/ui/auth/util/SessionUtils.kt | 25 + .../auth/util/data/AuthOperationManager.java | 117 -- .../ui/auth/util/data/ContinueUrlBuilder.java | 62 - .../ui/auth/util/data/EmailLinkParser.java | 88 - .../data/EmailLinkPersistenceManager.java | 165 -- .../ui/auth/util/data/PhoneNumberUtils.java | 478 ------ .../util/data/PrivacyDisclosureUtils.java | 81 - .../auth/util/data/ProviderAvailability.java | 28 - .../ui/auth/util/data/ProviderUtils.java | 280 ---- .../ui/auth/util/data/SessionUtils.java | 26 - .../ui/auth/util/data/TaskFailureLogger.java | 22 - .../firebase/ui/auth/util/package-info.java | 20 - .../util/ui/BucketedTextChangeListener.java | 129 -- .../firebase/ui/auth/util/ui/FlowUtils.java | 71 - .../firebase/ui/auth/util/ui/ImeHelper.java | 36 - .../ui/auth/util/ui/PreambleHandler.java | 146 -- .../firebase/ui/auth/util/ui/TextHelper.java | 31 - .../ui/fieldvalidators/BaseValidator.java | 47 - .../fieldvalidators/EmailFieldValidator.java | 36 - .../ui/fieldvalidators/NoOpValidator.java | 21 - .../PasswordFieldValidator.java | 37 - .../RequiredFieldValidator.java | 38 - .../util/ui/fieldvalidators/package-info.java | 20 - .../ui/auth/viewmodel/AuthViewModelBase.java | 54 - .../ui/auth/viewmodel/OperableViewModel.java | 27 - .../ui/auth/viewmodel/ProviderSignInBase.java | 56 - .../ui/auth/viewmodel/RequestCodes.java | 64 - .../ui/auth/viewmodel/ResourceObserver.java | 88 - .../auth/viewmodel/SignInViewModelBase.java | 44 - .../ui/auth/viewmodel/ViewModelBase.java | 44 - .../CredentialManagerHandler.kt | 109 -- .../email/EmailLinkSendEmailHandler.java | 82 - .../email/EmailLinkSignInHandler.java | 244 --- .../email/EmailProviderResponseHandler.java | 135 -- .../email/RecoverPasswordHandler.java | 34 - .../email/WelcomeBackPasswordHandler.java | 126 -- .../LinkingSocialProviderResponseHandler.java | 141 -- .../idp/SocialProviderResponseHandler.java | 202 --- .../phone/PhoneProviderResponseHandler.java | 52 - .../auth/{compose => }/AuthExceptionTest.kt | 0 .../{compose => }/AuthFlowControllerTest.kt | 6 - .../java/com/firebase/ui/auth/AuthUITest.java | 359 ----- .../{compose => }/FirebaseAuthActivityTest.kt | 3 - .../FirebaseAuthUIAuthStateTest.kt | 0 .../auth/{compose => }/FirebaseAuthUITest.kt | 0 .../firebase/ui/auth/SessionUtilsTest.java | 21 - .../com/firebase/ui/auth/TestApplication.java | 16 - .../configuration/AuthUIConfigurationTest.kt | 0 .../configuration/MfaConfigurationTest.kt | 0 .../configuration/PasswordRuleTest.kt | 0 ...AnonymousAuthProviderFirebaseAuthUITest.kt | 0 .../auth_provider/AuthProviderTest.kt | 0 .../EmailAuthProviderFirebaseAuthUITest.kt | 0 .../FacebookAuthProviderFirebaseAuthUI.kt | 0 .../GoogleAuthProviderFirebaseAuthUITest.kt | 0 .../OAuthProviderFirebaseAuthUITest.kt | 0 .../PhoneAuthProviderFirebaseAuthUITest.kt | 0 .../configuration/theme/AuthUIThemeTest.kt | 0 .../validators/EmailValidatorTest.kt | 0 .../validators/PasswordValidatorTest.kt | 0 .../PasswordCredentialHandlerTest.kt | 0 .../ui/auth/data/ContinueUrlBuilderTest.java | 84 - .../{compose => }/data/CountryDataTest.kt | 1 + .../ui/auth/data/EmailLinkParserTest.java | 82 - .../data/EmailLinkPersistanceManagerTest.java | 86 - .../mfa/MfaChallengeContentStateTest.kt | 0 .../mfa/MfaEnrollmentContentStateTest.kt | 0 .../mfa/MfaEnrollmentStepTest.kt | 0 .../mfa/SmsEnrollmentHandlerTest.kt | 0 .../mfa/TotpEnrollmentHandlerTest.kt | 0 .../auth/{compose => }/mfa/TotpSecretTest.kt | 0 .../ui/auth/testhelpers/AutoCompleteTask.java | 178 -- .../ui/auth/testhelpers/AutoContinueTask.java | 39 - .../testhelpers/FakeAdditionalUserInfo.java | 44 - .../ui/auth/testhelpers/FakeAuthResult.java | 67 - .../FakeSignInMethodQueryResult.java | 35 - .../ui/auth/testhelpers/ResourceMatchers.java | 54 - .../ui/auth/testhelpers/TestConstants.java | 30 - .../ui/auth/testhelpers/TestHelper.java | 241 --- .../ui/components/AuthProviderButtonTest.kt | 0 .../ui/components/AuthTextFieldTest.kt | 0 .../ErrorRecoveryDialogLogicTest.kt | 0 .../ui/auth/ui/email/EmailActivityTest.java | 209 --- .../email/WelcomeBackPasswordPromptTest.java | 84 - .../ui/idp/AuthMethodPickerActivityTest.java | 195 --- .../ui/method_picker/AuthMethodPickerTest.kt | 0 .../phone/BucketedTextChangeListenerTest.java | 113 -- .../ui/auth/ui/phone/CountryInfoTests.java | 111 -- .../ui/auth/ui/phone/PhoneNumberTest.java | 96 -- .../auth/ui/phone/PhoneNumberUtilsTest.java | 104 -- .../ui/auth/ui/phone/PhoneTestConstants.java | 29 - .../ui/auth/ui/phone/SpacedEditTextTest.java | 131 -- .../ui/screens/MfaChallengeScreenTest.kt | 0 .../ui/screens/MfaEnrollmentScreenTest.kt | 0 .../util/MockPersistenceManager.kt | 0 .../viewmodel/AnonymousSignInHandlerTest.java | 108 -- .../CredentialManagerHandlerTest.java | 115 -- .../EmailLinkSendEmailHandlerTest.java | 185 --- .../viewmodel/EmailLinkSignInHandlerTest.java | 691 -------- ...IdpAnonymousUpgradeLinkingHandlerTest.java | 164 -- .../GenericIdpSignInHandlerTest.java | 359 ----- ...kingSocialProviderResponseHandlerTest.java | 291 ---- .../PhoneProviderResponseHandlerTest.java | 147 -- .../viewmodel/RecoverPasswordHandlerTest.java | 142 -- .../SocialProviderResponseHandlerTest.java | 352 ---- .../WelcomeBackPasswordHandlerTest.java | 261 --- composeapp/build.gradle.kts | 77 - composeapp/public/.well-known/assetlinks.json | 10 - composeapp/public/index.html | 12 - composeapp/src/main/AndroidManifest.xml | 60 - .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - composeapp/src/main/res/values/colors.xml | 10 - composeapp/src/main/res/values/strings.xml | 10 - .../ui/auth/compose/ui/AccessibilityTest.kt | 4 +- .../compose/ui/screens/PhoneAuthScreenTest.kt | 2 +- settings.gradle | 1 - 366 files changed, 445 insertions(+), 22896 deletions(-) rename {composeapp => app}/.gitignore (100%) rename {composeapp => app}/proguard-rules.pro (100%) rename {composeapp => app}/src/main/ic_launcher-playstore.png (100%) rename {composeapp => app}/src/main/java/com/firebase/composeapp/AuthFlowControllerDemoActivity.kt (99%) rename {composeapp => app}/src/main/java/com/firebase/composeapp/CustomSlotsThemingDemoActivity.kt (99%) rename {composeapp => app}/src/main/java/com/firebase/composeapp/HighLevelApiDemoActivity.kt (99%) rename {composeapp => app}/src/main/java/com/firebase/composeapp/MainActivity.kt (99%) rename {composeapp => app}/src/main/java/com/firebase/composeapp/ui/theme/Color.kt (85%) rename {composeapp => app}/src/main/java/com/firebase/composeapp/ui/theme/Theme.kt (97%) rename {composeapp => app}/src/main/java/com/firebase/composeapp/ui/theme/Type.kt (95%) delete mode 100644 app/src/main/java/com/firebase/uidemo/ChooserActivity.java delete mode 100644 app/src/main/java/com/firebase/uidemo/FirebaseUIDemo.java delete mode 100644 app/src/main/java/com/firebase/uidemo/auth/AnonymousUpgradeActivity.java delete mode 100644 app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java delete mode 100644 app/src/main/java/com/firebase/uidemo/auth/SignedInActivity.java delete mode 100644 app/src/main/java/com/firebase/uidemo/database/AbstractChat.java delete mode 100644 app/src/main/java/com/firebase/uidemo/database/ChatHolder.java delete mode 100644 app/src/main/java/com/firebase/uidemo/database/firestore/Chat.java delete mode 100644 app/src/main/java/com/firebase/uidemo/database/firestore/FirestoreChatActivity.java delete mode 100644 app/src/main/java/com/firebase/uidemo/database/firestore/FirestorePagingActivity.java delete mode 100644 app/src/main/java/com/firebase/uidemo/database/realtime/Chat.java delete mode 100644 app/src/main/java/com/firebase/uidemo/database/realtime/FirebaseDbPagingActivity.java delete mode 100644 app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatActivity.java delete mode 100644 app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatIndexActivity.java delete mode 100644 app/src/main/java/com/firebase/uidemo/storage/ImageActivity.java delete mode 100644 app/src/main/java/com/firebase/uidemo/storage/MyAppGlideModule.java delete mode 100644 app/src/main/java/com/firebase/uidemo/util/ConfigurationUtils.java delete mode 100644 app/src/main/java/com/firebase/uidemo/util/SignInResultNotifier.java rename {composeapp => app}/src/main/res/drawable-hdpi/firebase_auth.png (100%) delete mode 100644 app/src/main/res/drawable-hdpi/firebase_auth_120dp.png rename {composeapp => app}/src/main/res/drawable-mdpi/firebase_auth.png (100%) delete mode 100644 app/src/main/res/drawable-mdpi/firebase_auth_120dp.png rename {composeapp => app}/src/main/res/drawable-v24/ic_launcher_foreground.xml (100%) rename {composeapp => app}/src/main/res/drawable-xhdpi/firebase_auth.png (100%) delete mode 100644 app/src/main/res/drawable-xhdpi/firebase_auth_120dp.png rename {composeapp => app}/src/main/res/drawable-xxhdpi/firebase_auth.png (100%) delete mode 100644 app/src/main/res/drawable-xxhdpi/firebase_auth_120dp.png rename {composeapp => app}/src/main/res/drawable-xxxhdpi/firebase_auth.png (100%) delete mode 100644 app/src/main/res/drawable-xxxhdpi/firebase_auth_120dp.png delete mode 100644 app/src/main/res/drawable/custom_bg_gradient.xml delete mode 100644 app/src/main/res/drawable/ic_anon_user_48dp.xml delete mode 100644 app/src/main/res/drawable/ic_chat_message_arrow.xml delete mode 100644 app/src/main/res/drawable/ic_chat_message_background.xml rename {composeapp => app}/src/main/res/drawable/ic_discord_24dp.xml (100%) delete mode 100644 app/src/main/res/drawable/ic_googleg_color_144dp.xml rename {composeapp => app}/src/main/res/drawable/ic_launcher_background.xml (100%) rename {composeapp => app}/src/main/res/drawable/ic_line_logo_24dp.xml (100%) delete mode 100644 app/src/main/res/layout-land/auth_method_picker_custom_layout.xml delete mode 100644 app/src/main/res/layout/activity_anonymous_upgrade.xml delete mode 100644 app/src/main/res/layout/activity_chat.xml delete mode 100644 app/src/main/res/layout/activity_chooser.xml delete mode 100644 app/src/main/res/layout/activity_chooser_item.xml delete mode 100644 app/src/main/res/layout/activity_database_paging.xml delete mode 100644 app/src/main/res/layout/activity_firestore_paging.xml delete mode 100644 app/src/main/res/layout/activity_image.xml delete mode 100644 app/src/main/res/layout/auth_method_picker_custom_layout.xml delete mode 100644 app/src/main/res/layout/auth_ui_layout.xml delete mode 100644 app/src/main/res/layout/item_item.xml delete mode 100644 app/src/main/res/layout/message.xml delete mode 100644 app/src/main/res/layout/signed_in_layout.xml delete mode 100644 app/src/main/res/menu/menu_paging.xml delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png rename {composeapp => app}/src/main/res/mipmap-hdpi/ic_launcher.webp (100%) delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png rename {composeapp => app}/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp (100%) delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png rename {composeapp => app}/src/main/res/mipmap-hdpi/ic_launcher_round.webp (100%) delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png rename {composeapp => app}/src/main/res/mipmap-mdpi/ic_launcher.webp (100%) delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png rename {composeapp => app}/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp (100%) delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png rename {composeapp => app}/src/main/res/mipmap-mdpi/ic_launcher_round.webp (100%) delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png rename {composeapp => app}/src/main/res/mipmap-xhdpi/ic_launcher.webp (100%) delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png rename {composeapp => app}/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp (100%) delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png rename {composeapp => app}/src/main/res/mipmap-xhdpi/ic_launcher_round.webp (100%) delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename {composeapp => app}/src/main/res/mipmap-xxhdpi/ic_launcher.webp (100%) delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png rename {composeapp => app}/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp (100%) delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png rename {composeapp => app}/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp (100%) delete mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename {composeapp => app}/src/main/res/mipmap-xxxhdpi/ic_launcher.webp (100%) delete mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png rename {composeapp => app}/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp (100%) delete mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png rename {composeapp => app}/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp (100%) delete mode 100644 app/src/main/res/values-w820dp/dimens.xml delete mode 100644 app/src/main/res/values/config.xml delete mode 100644 app/src/main/res/values/dimens.xml rename {composeapp => app}/src/main/res/values/ic_launcher_background.xml (100%) delete mode 100644 app/src/main/res/values/styles.xml rename {composeapp => app}/src/main/res/values/themes.xml (100%) delete mode 100644 app/src/main/res/xml-v25/shortcuts.xml rename auth/src/main/java/com/firebase/ui/auth/{compose => }/AuthException.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/AuthFlowController.kt (100%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/AuthMethodPickerLayout.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/AuthState.kt (99%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/AuthUI.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ErrorCodes.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/FirebaseAuthActivity.kt (98%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/FirebaseAuthAnonymousUpgradeException.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/FirebaseAuthUI.kt (99%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/FirebaseAuthUIActivityResultContract.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/FirebaseUIComposeRegistrar.kt (100%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/FirebaseUiException.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/FirebaseUiUserCollisionException.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/IdpResponse.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/KickoffActivity.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/AuthUIConfiguration.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/MfaConfiguration.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/MfaFactor.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/PasswordRule.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/AnonymousAuthProvider+FirebaseAuthUI.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/AuthProvider.kt (99%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt (99%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/FacebookAuthProvider+FirebaseAuthUI.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/GoogleAuthProvider+FirebaseAuthUI.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/OAuthProvider+FirebaseAuthUI.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/PhoneAuthProvider+FirebaseAuthUI.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/string_provider/AuthUIStringProvider.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/string_provider/AuthUIStringProviderSample.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/string_provider/DefaultAuthUIStringProvider.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/theme/AuthUIAsset.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/theme/AuthUITheme.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/theme/ProviderStyleDefaults.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/validators/EmailValidator.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/validators/FieldValidationStatus.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/validators/FieldValidator.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/validators/GeneralFieldValidator.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/validators/PasswordValidator.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/validators/PhoneNumberValidator.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/configuration/validators/VerificationCodeValidator.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/credentialmanager/PasswordCredential.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/credentialmanager/PasswordCredentialHandler.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/data/Countries.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/data/CountryData.kt (100%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/client/AuthUiInitProvider.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/CountryInfo.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/FirebaseAuthUIAuthenticationResult.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/FlowParameters.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/IntentRequiredException.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/PendingIntentRequiredException.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/PhoneNumber.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/PhoneNumberVerificationRequiredException.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/Resource.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/State.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/User.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/model/UserCancellationException.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/remote/AnonymousSignInHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/remote/EmailSignInHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/remote/FacebookSignInHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/remote/GenericIdpAnonymousUpgradeLinkingHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/remote/GenericIdpSignInHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/remote/GoogleSignInHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/remote/PhoneSignInHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/remote/ProfileMerger.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/remote/SignInKickstarter.kt delete mode 100644 auth/src/main/java/com/firebase/ui/auth/data/remote/SingleProviderSignInHandler.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/mfa/MfaChallengeContentState.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/mfa/MfaEnrollmentContentState.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/mfa/MfaEnrollmentStep.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/mfa/MfaErrorMapper.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/mfa/SmsEnrollmentHandler.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/mfa/TotpEnrollmentHandler.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/mfa/TotpSecret.kt (100%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/AppCompatBase.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/FragmentBase.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/HelperActivityBase.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/InvisibleActivityBase.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/InvisibleFragmentBase.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/ProgressView.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/components/AuthProviderButton.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/components/AuthTextField.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/components/CountrySelector.kt (99%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/components/ErrorRecoveryDialog.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/components/QrCodeImage.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/components/ReauthenticationDialog.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/components/TermsAndPrivacyForm.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/components/TopLevelDialogController.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/components/VerificationCodeInputField.kt (100%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/credentials/CredentialSaveActivity.kt delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/CheckEmailFragment.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/CheckEmailHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/EmailActivity.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/EmailLinkCatcherActivity.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/EmailLinkCrossDeviceLinkingFragment.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/EmailLinkErrorRecoveryActivity.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/EmailLinkFragment.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/EmailLinkPromptEmailFragment.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/RecoverPasswordActivity.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/RegisterEmailFragment.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/TroubleSigningInFragment.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/WelcomeBackEmailLinkPrompt.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/WelcomeBackPasswordPrompt.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/email/package-info.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivity.kt delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/idp/SingleSignInActivity.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/idp/WelcomeBackIdpPrompt.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/idp/package-info.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/method_picker/AnnotatedStringResource.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/method_picker/AuthMethodPicker.kt (100%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/package-info.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/phone/CheckPhoneHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/phone/CheckPhoneNumberFragment.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/phone/CountryListSpinner.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/phone/PhoneActivity.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/phone/PhoneNumberVerificationHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/phone/PhoneVerification.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/phone/SpacedEditText.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/ui/phone/SubmitConfirmationCodeFragment.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/FirebaseAuthScreen.kt (99%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/MfaChallengeDefaults.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/MfaChallengeScreen.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/MfaEnrollmentDefaults.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/MfaEnrollmentScreen.kt (99%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/email/EmailAuthScreen.kt (99%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/email/ResetPasswordUI.kt (99%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/email/SignInEmailLinkUI.kt (99%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/email/SignInUI.kt (99%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/email/SignUpUI.kt (99%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/phone/EnterPhoneNumberUI.kt (95%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/phone/EnterVerificationCodeUI.kt (100%) rename auth/src/main/java/com/firebase/ui/auth/{compose => }/ui/screens/phone/PhoneAuthScreen.kt (99%) create mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ContinueUrlBuilder.kt rename auth/src/main/java/com/firebase/ui/auth/{compose/data => util}/CountryUtils.kt (88%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/CredentialUtils.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/util/EmailLinkConstants.kt (100%) create mode 100644 auth/src/main/java/com/firebase/ui/auth/util/EmailLinkParser.kt rename auth/src/main/java/com/firebase/ui/auth/{compose => }/util/EmailLinkPersistenceManager.kt (100%) delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ExtraConstants.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/FirebaseAuthError.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/GoogleApiUtils.java rename auth/src/main/java/com/firebase/ui/auth/{compose => }/util/PersistenceManager.kt (100%) create mode 100644 auth/src/main/java/com/firebase/ui/auth/util/PhoneNumberUtils.kt create mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ProviderAvailability.kt create mode 100644 auth/src/main/java/com/firebase/ui/auth/util/SessionUtils.kt delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/data/AuthOperationManager.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/data/ContinueUrlBuilder.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/data/EmailLinkParser.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/data/EmailLinkPersistenceManager.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/data/PhoneNumberUtils.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/data/PrivacyDisclosureUtils.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/data/ProviderAvailability.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/data/ProviderUtils.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/data/SessionUtils.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/data/TaskFailureLogger.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/package-info.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/BucketedTextChangeListener.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/FlowUtils.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/ImeHelper.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/PreambleHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/TextHelper.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/fieldvalidators/BaseValidator.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/fieldvalidators/EmailFieldValidator.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/fieldvalidators/NoOpValidator.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/fieldvalidators/PasswordFieldValidator.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/fieldvalidators/RequiredFieldValidator.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/util/ui/fieldvalidators/package-info.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/AuthViewModelBase.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/OperableViewModel.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/ProviderSignInBase.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/RequestCodes.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/ResourceObserver.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/SignInViewModelBase.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/ViewModelBase.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/credentialmanager/CredentialManagerHandler.kt delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/email/EmailLinkSendEmailHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/email/EmailLinkSignInHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/email/EmailProviderResponseHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/email/RecoverPasswordHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/email/WelcomeBackPasswordHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/idp/LinkingSocialProviderResponseHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/idp/SocialProviderResponseHandler.java delete mode 100644 auth/src/main/java/com/firebase/ui/auth/viewmodel/phone/PhoneProviderResponseHandler.java rename auth/src/test/java/com/firebase/ui/auth/{compose => }/AuthExceptionTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/AuthFlowControllerTest.kt (98%) delete mode 100644 auth/src/test/java/com/firebase/ui/auth/AuthUITest.java rename auth/src/test/java/com/firebase/ui/auth/{compose => }/FirebaseAuthActivityTest.kt (99%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/FirebaseAuthUIAuthStateTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/FirebaseAuthUITest.kt (100%) delete mode 100644 auth/src/test/java/com/firebase/ui/auth/SessionUtilsTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/TestApplication.java rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/AuthUIConfigurationTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/MfaConfigurationTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/PasswordRuleTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/AnonymousAuthProviderFirebaseAuthUITest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/AuthProviderTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/EmailAuthProviderFirebaseAuthUITest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/FacebookAuthProviderFirebaseAuthUI.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/GoogleAuthProviderFirebaseAuthUITest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/OAuthProviderFirebaseAuthUITest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/auth_provider/PhoneAuthProviderFirebaseAuthUITest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/theme/AuthUIThemeTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/validators/EmailValidatorTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/configuration/validators/PasswordValidatorTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/credentialmanager/PasswordCredentialHandlerTest.kt (100%) delete mode 100644 auth/src/test/java/com/firebase/ui/auth/data/ContinueUrlBuilderTest.java rename auth/src/test/java/com/firebase/ui/auth/{compose => }/data/CountryDataTest.kt (99%) delete mode 100644 auth/src/test/java/com/firebase/ui/auth/data/EmailLinkParserTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/data/EmailLinkPersistanceManagerTest.java rename auth/src/test/java/com/firebase/ui/auth/{compose => }/mfa/MfaChallengeContentStateTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/mfa/MfaEnrollmentContentStateTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/mfa/MfaEnrollmentStepTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/mfa/SmsEnrollmentHandlerTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/mfa/TotpEnrollmentHandlerTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/mfa/TotpSecretTest.kt (100%) delete mode 100644 auth/src/test/java/com/firebase/ui/auth/testhelpers/AutoCompleteTask.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/testhelpers/AutoContinueTask.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/testhelpers/FakeAdditionalUserInfo.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/testhelpers/FakeAuthResult.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/testhelpers/FakeSignInMethodQueryResult.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/testhelpers/ResourceMatchers.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/testhelpers/TestConstants.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/testhelpers/TestHelper.java rename auth/src/test/java/com/firebase/ui/auth/{compose => }/ui/components/AuthProviderButtonTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/ui/components/AuthTextFieldTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/ui/components/ErrorRecoveryDialogLogicTest.kt (100%) delete mode 100644 auth/src/test/java/com/firebase/ui/auth/ui/email/EmailActivityTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/ui/email/WelcomeBackPasswordPromptTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivityTest.java rename auth/src/test/java/com/firebase/ui/auth/{compose => }/ui/method_picker/AuthMethodPickerTest.kt (100%) delete mode 100644 auth/src/test/java/com/firebase/ui/auth/ui/phone/BucketedTextChangeListenerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/ui/phone/CountryInfoTests.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/ui/phone/PhoneNumberTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/ui/phone/PhoneNumberUtilsTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/ui/phone/PhoneTestConstants.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/ui/phone/SpacedEditTextTest.java rename auth/src/test/java/com/firebase/ui/auth/{compose => }/ui/screens/MfaChallengeScreenTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/ui/screens/MfaEnrollmentScreenTest.kt (100%) rename auth/src/test/java/com/firebase/ui/auth/{compose => }/util/MockPersistenceManager.kt (100%) delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/AnonymousSignInHandlerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/CredentialManagerHandlerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/EmailLinkSendEmailHandlerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/EmailLinkSignInHandlerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/GenericIdpAnonymousUpgradeLinkingHandlerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/GenericIdpSignInHandlerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/LinkingSocialProviderResponseHandlerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/PhoneProviderResponseHandlerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/RecoverPasswordHandlerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/SocialProviderResponseHandlerTest.java delete mode 100644 auth/src/test/java/com/firebase/ui/auth/viewmodel/WelcomeBackPasswordHandlerTest.java delete mode 100644 composeapp/build.gradle.kts delete mode 100644 composeapp/public/.well-known/assetlinks.json delete mode 100644 composeapp/public/index.html delete mode 100644 composeapp/src/main/AndroidManifest.xml delete mode 100644 composeapp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 composeapp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 composeapp/src/main/res/values/colors.xml delete mode 100644 composeapp/src/main/res/values/strings.xml diff --git a/composeapp/.gitignore b/app/.gitignore similarity index 100% rename from composeapp/.gitignore rename to app/.gitignore diff --git a/app/build.gradle.kts b/app/build.gradle.kts index cec75d966..c6ddb0f50 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,102 +1,72 @@ -// NOTE: this project uses Gradle Kotlin DSL. More common build.gradle instructions can be found in -// the main README. plugins { - id("com.android.application") + id("com.android.application") + id("org.jetbrains.kotlin.android") + id("org.jetbrains.kotlin.plugin.compose") + id("com.google.gms.google-services") } android { - compileSdk = Config.SdkVersions.compile - namespace = "com.firebase.uidemo" + compileSdk = Config.SdkVersions.compile defaultConfig { + applicationId = "com.firebase.uidemo" minSdk = Config.SdkVersions.min targetSdk = Config.SdkVersions.target - - versionName = Config.version versionCode = 1 + versionName = "1.0" - resourcePrefix("fui_") - vectorDrawables.useSupportLibrary = true - } - - defaultConfig { - multiDexEnabled = true + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } buildTypes { - named("release").configure { - // For the purposes of the sample, allow testing of a proguarded release build - // using the debug key - signingConfig = signingConfigs["debug"] - - postprocessing { - isRemoveUnusedCode = true - isRemoveUnusedResources = true - isObfuscate = true - isOptimizeCode = true + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + // Only sign with debug keystore if it exists (for local testing) + val debugKeystoreFile = file("${System.getProperty("user.home")}/.android/debug.keystore") + if (debugKeystoreFile.exists()) { + signingConfig = signingConfigs.getByName("debug") } } } - - lint { - // Common lint options across all modules - - disable += mutableSetOf( - "IconExpectedSize", - "InvalidPackage", // Firestore uses GRPC which makes lint mad - "NewerVersionAvailable", "GradleDependency", // For reproducible builds - "SelectableText", "SyntheticAccessor", // We almost never care about this - "UnusedIds", "MediaCapabilities" // TODO(rosariopfernandes): remove this once we confirm - // it builds successfully - ) - - // Module-specific - disable += mutableSetOf("ResourceName", "MissingTranslation", "DuplicateStrings") - - checkAllWarnings = true - warningsAsErrors = true - abortOnError = true - - baseline = file("$rootDir/library/quality/lint-baseline.xml") - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" } - buildFeatures { - viewBinding = true + compose = true } } dependencies { - implementation(Config.Libs.Androidx.materialDesign) - implementation(Config.Libs.Androidx.multidex) - implementation(project(":auth")) - implementation(project(":firestore")) - implementation(project(":database")) - implementation(project(":storage")) + implementation(Config.Libs.Kotlin.jvm) + implementation(Config.Libs.Androidx.lifecycleRuntime) + implementation(Config.Libs.Androidx.Compose.activityCompose) + implementation(platform(Config.Libs.Androidx.Compose.bom)) + implementation(Config.Libs.Androidx.Compose.ui) + implementation(Config.Libs.Androidx.Compose.uiGraphics) + implementation(Config.Libs.Androidx.Compose.toolingPreview) + implementation(Config.Libs.Androidx.Compose.material3) + + + // Facebook implementation(Config.Libs.Provider.facebook) - // Needed to override Facebook - implementation(Config.Libs.Androidx.cardView) - implementation(Config.Libs.Androidx.customTabs) - implementation(Config.Libs.Misc.glide) - annotationProcessor(Config.Libs.Misc.glideCompiler) + testImplementation(Config.Libs.Test.junit) + androidTestImplementation(Config.Libs.Test.junitExt) + androidTestImplementation(platform(Config.Libs.Androidx.Compose.bom)) + androidTestImplementation(Config.Libs.Test.composeUiTestJunit4) - // Used for FirestorePagingActivity - implementation(Config.Libs.Androidx.paging) + debugImplementation(Config.Libs.Androidx.Compose.tooling) - // The following dependencies are not required to use the Firebase UI library. - // They are used to make some aspects of the demo app implementation simpler for - // demonstrative purposes, and you may find them useful in your own apps; YMMV. - implementation(Config.Libs.Misc.permissions) - implementation(Config.Libs.Androidx.constraint) - debugImplementation(Config.Libs.Misc.leakCanary) + implementation(platform(Config.Libs.Firebase.bom)) } - -apply(plugin = "com.google.gms.google-services") diff --git a/composeapp/proguard-rules.pro b/app/proguard-rules.pro similarity index 100% rename from composeapp/proguard-rules.pro rename to app/proguard-rules.pro diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 60ccc6600..0139f125b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,77 +1,60 @@ - + - - + - - + - + + + + + + + + + + - - - - - - + android:name=".HighLevelApiDemoActivity" + android:label="High-Level API Demo" + android:exported="false" + android:theme="@style/Theme.FirebaseUIAndroid" /> - + android:name=".AuthFlowControllerDemoActivity" + android:label="Low-Level API Demo" + android:exported="false" + android:theme="@style/Theme.FirebaseUIAndroid" /> - - - - - - - - - - + android:name=".CustomSlotsThemingDemoActivity" + android:label="Custom Slots & Theming Demo" + android:exported="false" + android:theme="@style/Theme.FirebaseUIAndroid" /> - \ No newline at end of file + diff --git a/composeapp/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png similarity index 100% rename from composeapp/src/main/ic_launcher-playstore.png rename to app/src/main/ic_launcher-playstore.png diff --git a/composeapp/src/main/java/com/firebase/composeapp/AuthFlowControllerDemoActivity.kt b/app/src/main/java/com/firebase/composeapp/AuthFlowControllerDemoActivity.kt similarity index 99% rename from composeapp/src/main/java/com/firebase/composeapp/AuthFlowControllerDemoActivity.kt rename to app/src/main/java/com/firebase/composeapp/AuthFlowControllerDemoActivity.kt index dfdcb0cab..efca8c65e 100644 --- a/composeapp/src/main/java/com/firebase/composeapp/AuthFlowControllerDemoActivity.kt +++ b/app/src/main/java/com/firebase/composeapp/AuthFlowControllerDemoActivity.kt @@ -1,4 +1,4 @@ -package com.firebase.composeapp +package com.firebase.uidemo import android.app.Activity import android.content.Context @@ -86,7 +86,7 @@ class AuthFlowControllerDemoActivity : ComponentActivity() { url = "https://temp-test-aa342.firebaseapp.com" handleCodeInApp = true setAndroidPackageName( - "com.firebase.composeapp", + "com.firebase.uidemo", true, null ) diff --git a/composeapp/src/main/java/com/firebase/composeapp/CustomSlotsThemingDemoActivity.kt b/app/src/main/java/com/firebase/composeapp/CustomSlotsThemingDemoActivity.kt similarity index 99% rename from composeapp/src/main/java/com/firebase/composeapp/CustomSlotsThemingDemoActivity.kt rename to app/src/main/java/com/firebase/composeapp/CustomSlotsThemingDemoActivity.kt index 75e9cb7d5..bd5cc1088 100644 --- a/composeapp/src/main/java/com/firebase/composeapp/CustomSlotsThemingDemoActivity.kt +++ b/app/src/main/java/com/firebase/composeapp/CustomSlotsThemingDemoActivity.kt @@ -1,4 +1,4 @@ -package com.firebase.composeapp +package com.firebase.uidemo import android.os.Bundle import android.util.Log @@ -25,9 +25,9 @@ import com.firebase.ui.auth.compose.configuration.auth_provider.AuthProvider import com.firebase.ui.auth.compose.configuration.string_provider.LocalAuthUIStringProvider import com.firebase.ui.auth.compose.configuration.theme.AuthUIAsset import com.firebase.ui.auth.compose.configuration.theme.AuthUITheme -import com.firebase.ui.auth.compose.ui.screens.EmailAuthContentState -import com.firebase.ui.auth.compose.ui.screens.EmailAuthMode -import com.firebase.ui.auth.compose.ui.screens.EmailAuthScreen +import com.firebase.ui.auth.compose.ui.screens.email.EmailAuthContentState +import com.firebase.ui.auth.compose.ui.screens.email.EmailAuthMode +import com.firebase.ui.auth.compose.ui.screens.email.EmailAuthScreen import com.firebase.ui.auth.compose.ui.screens.phone.PhoneAuthContentState import com.firebase.ui.auth.compose.ui.screens.phone.PhoneAuthScreen import com.firebase.ui.auth.compose.ui.screens.phone.PhoneAuthStep diff --git a/composeapp/src/main/java/com/firebase/composeapp/HighLevelApiDemoActivity.kt b/app/src/main/java/com/firebase/composeapp/HighLevelApiDemoActivity.kt similarity index 99% rename from composeapp/src/main/java/com/firebase/composeapp/HighLevelApiDemoActivity.kt rename to app/src/main/java/com/firebase/composeapp/HighLevelApiDemoActivity.kt index 3ec0d3a1e..22579a41a 100644 --- a/composeapp/src/main/java/com/firebase/composeapp/HighLevelApiDemoActivity.kt +++ b/app/src/main/java/com/firebase/composeapp/HighLevelApiDemoActivity.kt @@ -1,4 +1,4 @@ -package com.firebase.composeapp +package com.firebase.uidemo import android.os.Bundle import android.util.Log @@ -65,7 +65,7 @@ class HighLevelApiDemoActivity : ComponentActivity() { url = "https://temp-test-aa342.firebaseapp.com" handleCodeInApp = true setAndroidPackageName( - "com.firebase.composeapp", + "com.firebase.uidemo", true, null ) diff --git a/composeapp/src/main/java/com/firebase/composeapp/MainActivity.kt b/app/src/main/java/com/firebase/composeapp/MainActivity.kt similarity index 99% rename from composeapp/src/main/java/com/firebase/composeapp/MainActivity.kt rename to app/src/main/java/com/firebase/composeapp/MainActivity.kt index 039e20115..9fdcf2901 100644 --- a/composeapp/src/main/java/com/firebase/composeapp/MainActivity.kt +++ b/app/src/main/java/com/firebase/composeapp/MainActivity.kt @@ -1,4 +1,4 @@ -package com.firebase.composeapp +package com.firebase.uidemo import android.content.Intent import android.os.Bundle diff --git a/composeapp/src/main/java/com/firebase/composeapp/ui/theme/Color.kt b/app/src/main/java/com/firebase/composeapp/ui/theme/Color.kt similarity index 85% rename from composeapp/src/main/java/com/firebase/composeapp/ui/theme/Color.kt rename to app/src/main/java/com/firebase/composeapp/ui/theme/Color.kt index 994915613..ead7d1c46 100644 --- a/composeapp/src/main/java/com/firebase/composeapp/ui/theme/Color.kt +++ b/app/src/main/java/com/firebase/composeapp/ui/theme/Color.kt @@ -1,4 +1,4 @@ -package com.firebase.composeapp.ui.theme +package com.firebase.uidemo.ui.theme import androidx.compose.ui.graphics.Color diff --git a/composeapp/src/main/java/com/firebase/composeapp/ui/theme/Theme.kt b/app/src/main/java/com/firebase/composeapp/ui/theme/Theme.kt similarity index 97% rename from composeapp/src/main/java/com/firebase/composeapp/ui/theme/Theme.kt rename to app/src/main/java/com/firebase/composeapp/ui/theme/Theme.kt index 08bd9441a..4d34bc26d 100644 --- a/composeapp/src/main/java/com/firebase/composeapp/ui/theme/Theme.kt +++ b/app/src/main/java/com/firebase/composeapp/ui/theme/Theme.kt @@ -1,4 +1,4 @@ -package com.firebase.composeapp.ui.theme +package com.firebase.uidemo.ui.theme import android.app.Activity import android.os.Build diff --git a/composeapp/src/main/java/com/firebase/composeapp/ui/theme/Type.kt b/app/src/main/java/com/firebase/composeapp/ui/theme/Type.kt similarity index 95% rename from composeapp/src/main/java/com/firebase/composeapp/ui/theme/Type.kt rename to app/src/main/java/com/firebase/composeapp/ui/theme/Type.kt index ea0657654..f93d7a7ce 100644 --- a/composeapp/src/main/java/com/firebase/composeapp/ui/theme/Type.kt +++ b/app/src/main/java/com/firebase/composeapp/ui/theme/Type.kt @@ -1,4 +1,4 @@ -package com.firebase.composeapp.ui.theme +package com.firebase.uidemo.ui.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle diff --git a/app/src/main/java/com/firebase/uidemo/ChooserActivity.java b/app/src/main/java/com/firebase/uidemo/ChooserActivity.java deleted file mode 100644 index 4f7504299..000000000 --- a/app/src/main/java/com/firebase/uidemo/ChooserActivity.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2016 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.firebase.uidemo; - -import android.content.Intent; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.firebase.ui.auth.AuthUI; -import com.firebase.ui.auth.util.ExtraConstants; -import com.firebase.uidemo.auth.AnonymousUpgradeActivity; -import com.firebase.uidemo.auth.AuthUiActivity; -import com.firebase.uidemo.database.firestore.FirestoreChatActivity; -import com.firebase.uidemo.database.firestore.FirestorePagingActivity; -import com.firebase.uidemo.database.realtime.FirebaseDbPagingActivity; -import com.firebase.uidemo.database.realtime.RealtimeDbChatActivity; -import com.firebase.uidemo.databinding.ActivityChooserBinding; -import com.firebase.uidemo.storage.ImageActivity; - -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; -import androidx.appcompat.app.AppCompatActivity; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -public class ChooserActivity extends AppCompatActivity { - private ActivityChooserBinding mBinding; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if (AuthUI.canHandleIntent(getIntent())) { - Intent intent = new Intent(ChooserActivity.this, AuthUiActivity - .class); - intent.putExtra(ExtraConstants.EMAIL_LINK_SIGN_IN, getIntent().getData().toString()); - startActivity(intent); - finish(); - return; - } - mBinding = ActivityChooserBinding.inflate(getLayoutInflater()); - setContentView(mBinding.getRoot()); - - mBinding.activities.setLayoutManager(new LinearLayoutManager(this)); - mBinding.activities.setAdapter(new ActivityChooserAdapter()); - mBinding.activities.setHasFixedSize(true); - } - - private static class ActivityChooserAdapter - extends RecyclerView.Adapter { - private static final Class[] CLASSES = new Class[]{ - AuthUiActivity.class, - AnonymousUpgradeActivity.class, - FirestoreChatActivity.class, - FirestorePagingActivity.class, - RealtimeDbChatActivity.class, - FirebaseDbPagingActivity.class, - ImageActivity.class, - }; - - private static final int[] DESCRIPTION_NAMES = new int[]{ - R.string.title_auth_activity, - R.string.title_anonymous_upgrade, - R.string.title_firestore_activity, - R.string.title_firestore_paging_activity, - R.string.title_realtime_database_activity, - R.string.title_realtime_database_paging_activity, - R.string.title_storage_activity - }; - - private static final int[] DESCRIPTION_IDS = new int[]{ - R.string.desc_auth, - R.string.desc_anonymous_upgrade, - R.string.desc_firestore, - R.string.desc_firestore_paging, - R.string.desc_realtime_database, - R.string.desc_realtime_database_paging, - R.string.desc_storage - }; - - @Override - public ActivityStarterHolder onCreateViewHolder(ViewGroup parent, int viewType) { - return new ActivityStarterHolder( - LayoutInflater.from(parent.getContext()) - .inflate(R.layout.activity_chooser_item, parent, false)); - } - - @Override - public void onBindViewHolder(ActivityStarterHolder holder, int position) { - holder.bind(CLASSES[position], DESCRIPTION_NAMES[position], DESCRIPTION_IDS[position]); - } - - @Override - public int getItemCount() { - return CLASSES.length; - } - } - - private static class ActivityStarterHolder extends RecyclerView.ViewHolder - implements View.OnClickListener { - private TextView mTitle; - private TextView mDescription; - - private Class mStarterClass; - - public ActivityStarterHolder(View itemView) { - super(itemView); - mTitle = itemView.findViewById(R.id.text1); - mDescription = itemView.findViewById(R.id.text2); - } - - private void bind(Class aClass, @StringRes int name, @StringRes int description) { - mStarterClass = aClass; - - mTitle.setText(name); - mDescription.setText(description); - itemView.setOnClickListener(this); - } - - @Override - public void onClick(View v) { - itemView.getContext().startActivity(new Intent(itemView.getContext(), mStarterClass)); - } - } -} diff --git a/app/src/main/java/com/firebase/uidemo/FirebaseUIDemo.java b/app/src/main/java/com/firebase/uidemo/FirebaseUIDemo.java deleted file mode 100644 index db33245f8..000000000 --- a/app/src/main/java/com/firebase/uidemo/FirebaseUIDemo.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.firebase.uidemo; - -import androidx.appcompat.app.AppCompatDelegate; -import androidx.multidex.MultiDexApplication; - -public class FirebaseUIDemo extends MultiDexApplication { - static { - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY); - } -} diff --git a/app/src/main/java/com/firebase/uidemo/auth/AnonymousUpgradeActivity.java b/app/src/main/java/com/firebase/uidemo/auth/AnonymousUpgradeActivity.java deleted file mode 100644 index 4453c4cbd..000000000 --- a/app/src/main/java/com/firebase/uidemo/auth/AnonymousUpgradeActivity.java +++ /dev/null @@ -1,192 +0,0 @@ -package com.firebase.uidemo.auth; - -import android.content.Intent; -import android.os.Bundle; -import android.text.TextUtils; -import android.util.Log; -import android.view.View; -import android.widget.Toast; - -import com.firebase.ui.auth.AuthUI; -import com.firebase.ui.auth.ErrorCodes; -import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract; -import com.firebase.ui.auth.IdpResponse; -import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult; -import com.firebase.uidemo.R; -import com.firebase.uidemo.databinding.ActivityAnonymousUpgradeBinding; -import com.firebase.uidemo.util.ConfigurationUtils; -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.FirebaseAuth; -import com.google.firebase.auth.FirebaseUser; - -import java.util.List; - -import androidx.activity.result.ActivityResultCallback; -import androidx.activity.result.ActivityResultLauncher; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; - -public class AnonymousUpgradeActivity extends AppCompatActivity - implements ActivityResultCallback { - - private static final String TAG = "AccountLink"; - - private ActivityAnonymousUpgradeBinding mBinding; - - private AuthCredential mPendingCredential; - - private final ActivityResultLauncher signIn = - registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this); - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mBinding = ActivityAnonymousUpgradeBinding.inflate(getLayoutInflater()); - setContentView(mBinding.getRoot()); - - updateUI(); - - // Got here from AuthUIActivity, and we need to deal with a merge conflict - // Occurs after catching an email link - IdpResponse response = IdpResponse.fromResultIntent(getIntent()); - if (response != null) { - handleSignInResult(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, response); - } - - mBinding.anonSignIn.setOnClickListener(view -> signInAnonymously()); - mBinding.beginFlow.setOnClickListener(view -> startAuthUI()); - mBinding.resolveMerge.setOnClickListener(view -> resolveMerge()); - mBinding.signOut.setOnClickListener(view -> signOut()); - } - - public void signInAnonymously() { - FirebaseAuth.getInstance().signInAnonymously() - .addOnCompleteListener(this, task -> { - updateUI(); - - if (task.isSuccessful()) { - setStatus("Signed in anonymously as user " - + getUserIdentifier(task.getResult().getUser())); - } else { - setStatus("Anonymous sign in failed."); - } - }); - } - - public void startAuthUI() { - List providers = ConfigurationUtils.getConfiguredProviders(this); - Intent signInIntent = AuthUI.getInstance().createSignInIntentBuilder() - .setLogo(R.drawable.firebase_auth_120dp) - .setAvailableProviders(providers) - .enableAnonymousUsersAutoUpgrade() - .build(); - signIn.launch(signInIntent); - } - - public void resolveMerge() { - if (mPendingCredential == null) { - Toast.makeText(this, "Nothing to resolve.", Toast.LENGTH_SHORT).show(); - return; - } - - // TODO: Show how to do good data moving - - FirebaseAuth.getInstance().signInWithCredential(mPendingCredential) - .addOnCompleteListener(this, task -> { - mPendingCredential = null; - updateUI(); - - if (task.isSuccessful()) { - setStatus("Signed in as " + getUserIdentifier(task.getResult() - .getUser())); - } else { - Log.w(TAG, "Merge failed", task.getException()); - setStatus("Failed to resolve merge conflict, see logs."); - } - }); - } - - public void signOut() { - AuthUI.getInstance().signOut(this) - .addOnCompleteListener(task -> { - setStatus(null); - updateUI(); - }); - } - - private void handleSignInResult(int resultCode, @Nullable IdpResponse response) { - if (response == null) { - // User pressed back button - return; - } - if (resultCode == RESULT_OK) { - setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance() - .getCurrentUser())); - } else if (response.getError().getErrorCode() == ErrorCodes - .ANONYMOUS_UPGRADE_MERGE_CONFLICT) { - setStatus("Merge conflict: user already exists."); - mBinding.resolveMerge.setEnabled(true); - mPendingCredential = response.getCredentialForLinking(); - } else { - Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show(); - Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError()); - } - - updateUI(); - } - - private void updateUI() { - FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); - - if (currentUser == null) { - // Not signed in - mBinding.anonSignIn.setEnabled(true); - mBinding.beginFlow.setEnabled(false); - mBinding.resolveMerge.setEnabled(false); - mBinding.signOut.setEnabled(false); - } else if (mPendingCredential == null && currentUser.isAnonymous()) { - // Anonymous user, waiting for linking - mBinding.anonSignIn.setEnabled(false); - mBinding.beginFlow.setEnabled(true); - mBinding.resolveMerge.setEnabled(false); - mBinding.signOut.setEnabled(true); - } else if (mPendingCredential == null && !currentUser.isAnonymous()) { - // Fully signed in - mBinding.anonSignIn.setEnabled(false); - mBinding.beginFlow.setEnabled(false); - mBinding.resolveMerge.setEnabled(false); - mBinding.signOut.setEnabled(true); - } else if (mPendingCredential != null) { - // Signed in anonymous, awaiting merge conflict - mBinding.anonSignIn.setEnabled(false); - mBinding.beginFlow.setEnabled(false); - mBinding.resolveMerge.setEnabled(true); - mBinding.signOut.setEnabled(true); - } - } - - private void setStatus(String message) { - mBinding.statusText.setText(message); - } - - private String getUserIdentifier(FirebaseUser user) { - if (user.isAnonymous()) { - return user.getUid(); - } else if (!TextUtils.isEmpty(user.getEmail())) { - return user.getEmail(); - } else if (!TextUtils.isEmpty(user.getPhoneNumber())) { - return user.getPhoneNumber(); - } else { - return "unknown"; - } - } - - @Override - public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) { - handleSignInResult(result.getResultCode(), result.getIdpResponse()); - } -} diff --git a/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java b/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java deleted file mode 100644 index 0a8d44cd3..000000000 --- a/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright 2016 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.firebase.uidemo.auth; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; - -import com.firebase.ui.auth.AuthMethodPickerLayout; -import com.firebase.ui.auth.AuthUI; -import com.firebase.ui.auth.AuthUI.IdpConfig; -import com.firebase.ui.auth.ErrorCodes; -import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract; -import com.firebase.ui.auth.IdpResponse; -import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult; -import com.firebase.ui.auth.util.ExtraConstants; -import com.firebase.uidemo.R; -import com.firebase.uidemo.databinding.AuthUiLayoutBinding; -import com.firebase.uidemo.util.ConfigurationUtils; -import com.google.android.gms.common.Scopes; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.android.material.snackbar.Snackbar; -import com.google.firebase.auth.ActionCodeSettings; -import com.google.firebase.auth.AuthResult; -import com.google.firebase.auth.FirebaseAuth; - -import java.util.ArrayList; -import java.util.List; - -import androidx.activity.result.ActivityResultCallback; -import androidx.activity.result.ActivityResultLauncher; -import androidx.annotation.DrawableRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; -import androidx.annotation.StyleRes; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.app.AppCompatDelegate; - -public class AuthUiActivity extends AppCompatActivity - implements ActivityResultCallback { - private static final String TAG = "AuthUiActivity"; - - private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/"; - private static final String FIREBASE_TOS_URL = "https://firebase.google.com/terms/"; - private static final String GOOGLE_PRIVACY_POLICY_URL = "https://www.google" + - ".com/policies/privacy/"; - private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google" + - ".com/terms/analytics/#7_privacy"; - - private static final int RC_SIGN_IN = 100; - - private AuthUiLayoutBinding mBinding; - - private final ActivityResultLauncher signIn = - registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this); - - @NonNull - public static Intent createIntent(@NonNull Context context) { - return new Intent(context, AuthUiActivity.class); - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mBinding = AuthUiLayoutBinding.inflate(getLayoutInflater()); - setContentView(mBinding.getRoot()); - - // Workaround for vector drawables on API 19 - AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); - - if (ConfigurationUtils.isGoogleMisconfigured(this)) { - mBinding.googleProvider.setChecked(false); - mBinding.googleProvider.setEnabled(false); - mBinding.googleProvider.setText(R.string.google_label_missing_config); - setGoogleScopesEnabled(false); - } else { - setGoogleScopesEnabled(mBinding.googleProvider.isChecked()); - mBinding.googleProvider.setOnCheckedChangeListener((compoundButton, checked) -> setGoogleScopesEnabled(checked)); - } - - if (ConfigurationUtils.isFacebookMisconfigured(this)) { - mBinding.facebookProvider.setChecked(false); - mBinding.facebookProvider.setEnabled(false); - mBinding.facebookProvider.setText(R.string.facebook_label_missing_config); - setFacebookPermissionsEnabled(false); - } else { - setFacebookPermissionsEnabled(mBinding.facebookProvider.isChecked()); - mBinding.facebookProvider.setOnCheckedChangeListener((compoundButton, checked) -> setFacebookPermissionsEnabled(checked)); - } - - mBinding.emailLinkProvider.setOnCheckedChangeListener((buttonView, isChecked) -> flipPasswordProviderCheckbox(isChecked)); - - mBinding.emailProvider.setOnCheckedChangeListener((buttonView, isChecked) -> flipEmailLinkProviderCheckbox(isChecked)); - - mBinding.emailLinkProvider.setChecked(false); - mBinding.emailProvider.setChecked(true); - - // The custom layout in this app only supports Email and Google providers. - mBinding.customLayout.setOnCheckedChangeListener((compoundButton, checked) -> { - if (checked) { - mBinding.googleProvider.setChecked(true); - mBinding.emailProvider.setChecked(true); - - mBinding.facebookProvider.setChecked(false); - mBinding.twitterProvider.setChecked(false); - mBinding.emailLinkProvider.setChecked(false); - mBinding.phoneProvider.setChecked(false); - mBinding.anonymousProvider.setChecked(false); - mBinding.microsoftProvider.setChecked(false); - mBinding.yahooProvider.setChecked(false); - mBinding.appleProvider.setChecked(false); - mBinding.githubProvider.setChecked(false); - } - }); - - // useEmulator can't be reversed until the FirebaseApp is cleared, so we make this - // checkbox "sticky" until the app is restarted - mBinding.useAuthEmulator.setOnCheckedChangeListener((buttonView, isChecked) -> { - if (isChecked) { - mBinding.useAuthEmulator.setEnabled(false); - } - }); - - mBinding.signIn.setOnClickListener(view -> signIn()); - - if (ConfigurationUtils.isGoogleMisconfigured(this) - || ConfigurationUtils.isFacebookMisconfigured(this)) { - showSnackbar(R.string.configuration_required); - } - - catchEmailLinkSignIn(); - } - - public void catchEmailLinkSignIn() { - if (getIntent().getExtras() == null) { - return; - } - String link = getIntent().getExtras().getString(ExtraConstants.EMAIL_LINK_SIGN_IN); - if (link != null) { - signInWithEmailLink(link); - } - } - - public void flipPasswordProviderCheckbox(boolean emailLinkProviderIsChecked) { - if (emailLinkProviderIsChecked) { - mBinding.emailProvider.setChecked(false); - } - } - - public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) { - if (passwordProviderIsChecked) { - mBinding.emailLinkProvider.setChecked(false); - } - } - - public void signIn() { - signIn.launch(getSignInIntent(/*link=*/null)); - } - - public void signInWithEmailLink(@Nullable String link) { - signIn.launch(getSignInIntent(link)); - } - - @NonNull - public AuthUI getAuthUI() { - AuthUI authUI = AuthUI.getInstance(); - if (mBinding.useAuthEmulator.isChecked()) { - authUI.useEmulator("10.0.2.2", 9099); - } - - return authUI; - } - - private Intent getSignInIntent(@Nullable String link) { - AuthUI.SignInIntentBuilder builder = getAuthUI().createSignInIntentBuilder() - .setTheme(getSelectedTheme()) - .setLogo(getSelectedLogo()) - .setAvailableProviders(getSelectedProviders()) - .setCredentialManagerEnabled(mBinding.credentialSelectorEnabled.isChecked()); - - if (mBinding.customLayout.isChecked()) { - AuthMethodPickerLayout customLayout = new AuthMethodPickerLayout - .Builder(R.layout.auth_method_picker_custom_layout) - .setGoogleButtonId(R.id.custom_google_signin_button) - .setEmailButtonId(R.id.custom_email_signin_clickable_text) - .setTosAndPrivacyPolicyId(R.id.custom_tos_pp) - .build(); - - builder.setTheme(R.style.CustomTheme); - builder.setAuthMethodPickerLayout(customLayout); - } - - if (getSelectedTosUrl() != null && getSelectedPrivacyPolicyUrl() != null) { - builder.setTosAndPrivacyPolicyUrls( - getSelectedTosUrl(), - getSelectedPrivacyPolicyUrl()); - } - - if (link != null) { - builder.setEmailLink(link); - } - - FirebaseAuth auth = FirebaseAuth.getInstance(); - - if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) { - builder.enableAnonymousUsersAutoUpgrade(); - } - - builder.setAlwaysShowSignInMethodScreen(true); - return builder.build(); - } - - @Override - protected void onResume() { - super.onResume(); - FirebaseAuth auth = FirebaseAuth.getInstance(); - if (auth.getCurrentUser() != null && getIntent().getExtras() == null) { - startSignedInActivity(null); - finish(); - } - } - - private void handleSignInResponse(int resultCode, @Nullable IdpResponse response) { - // Successfully signed in - if (resultCode == RESULT_OK) { - startSignedInActivity(response); - finish(); - } else { - // Sign in failed - if (response == null) { - // User pressed back button - showSnackbar(R.string.sign_in_cancelled); - return; - } - - if (response.getError().getErrorCode() == ErrorCodes.NO_NETWORK) { - showSnackbar(R.string.no_internet_connection); - return; - } - - if (response.getError().getErrorCode() == ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT) { - Intent intent = new Intent(this, AnonymousUpgradeActivity.class).putExtra - (ExtraConstants.IDP_RESPONSE, response); - startActivity(intent); - } - - if (response.getError().getErrorCode() == ErrorCodes.ERROR_USER_DISABLED) { - showSnackbar(R.string.account_disabled); - return; - } - - showSnackbar(R.string.unknown_error); - Log.e(TAG, "Sign-in error: ", response.getError()); - } - } - - private void startSignedInActivity(@Nullable IdpResponse response) { - startActivity(SignedInActivity.createIntent(this, response)); - } - - @StyleRes - private int getSelectedTheme() { - if (mBinding.greenTheme.isChecked()) { - return R.style.GreenTheme; - } - - if (mBinding.appTheme.isChecked()) { - return R.style.AppTheme; - } - - return AuthUI.getDefaultTheme(); - } - - @DrawableRes - private int getSelectedLogo() { - if (mBinding.firebaseLogo.isChecked()) { - return R.drawable.firebase_auth_120dp; - } else if (mBinding.googleLogo.isChecked()) { - return R.drawable.ic_googleg_color_144dp; - } - return AuthUI.NO_LOGO; - } - - private List getSelectedProviders() { - List selectedProviders = new ArrayList<>(); - - if (mBinding.googleProvider.isChecked()) { - selectedProviders.add( - new IdpConfig.GoogleBuilder().setScopes(getGoogleScopes()).build()); - } - - if (mBinding.facebookProvider.isChecked()) { - selectedProviders.add(new IdpConfig.FacebookBuilder() - .setPermissions(getFacebookPermissions()) - .build()); - } - - if (mBinding.emailProvider.isChecked()) { - selectedProviders.add(new IdpConfig.EmailBuilder() - .setRequireName(mBinding.requireName.isChecked()) - .setAllowNewAccounts(mBinding.allowNewEmailAccounts.isChecked()) - .build()); - } - - if (mBinding.emailLinkProvider.isChecked()) { - ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder() - .setAndroidPackageName("com.firebase.uidemo", true, null) - .setHandleCodeInApp(true) - .setUrl("https://google.com") - .build(); - - selectedProviders.add(new IdpConfig.EmailBuilder() - .setAllowNewAccounts(mBinding.allowNewEmailAccounts.isChecked()) - .setActionCodeSettings(actionCodeSettings) - .enableEmailLinkSignIn() - .build()); - } - - if (mBinding.phoneProvider.isChecked()) { - selectedProviders.add(new IdpConfig.PhoneBuilder().build()); - } - - if (mBinding.anonymousProvider.isChecked()) { - selectedProviders.add(new IdpConfig.AnonymousBuilder().build()); - } - - if (mBinding.twitterProvider.isChecked()) { - selectedProviders.add(new IdpConfig.TwitterBuilder().build()); - } - - if (mBinding.microsoftProvider.isChecked()) { - selectedProviders.add(new IdpConfig.MicrosoftBuilder().build()); - } - - if (mBinding.yahooProvider.isChecked()) { - selectedProviders.add(new IdpConfig.YahooBuilder().build()); - } - - if (mBinding.appleProvider.isChecked()) { - selectedProviders.add(new IdpConfig.AppleBuilder().build()); - } - - if (mBinding.githubProvider.isChecked()) { - selectedProviders.add(new IdpConfig.GitHubBuilder().build()); - } - - return selectedProviders; - } - - @Nullable - private String getSelectedTosUrl() { - if (mBinding.googleTosPrivacy.isChecked()) { - return GOOGLE_TOS_URL; - } - - if (mBinding.firebaseTosPrivacy.isChecked()) { - return FIREBASE_TOS_URL; - } - - return null; - } - - @Nullable - private String getSelectedPrivacyPolicyUrl() { - if (mBinding.googleTosPrivacy.isChecked()) { - return GOOGLE_PRIVACY_POLICY_URL; - } - - if (mBinding.firebaseTosPrivacy.isChecked()) { - return FIREBASE_PRIVACY_POLICY_URL; - } - - return null; - } - - private void setGoogleScopesEnabled(boolean enabled) { - mBinding.googleScopesHeader.setEnabled(enabled); - mBinding.googleScopeDriveFile.setEnabled(enabled); - mBinding.googleScopeYoutubeData.setEnabled(enabled); - } - - private void setFacebookPermissionsEnabled(boolean enabled) { - mBinding.facebookPermissionsHeader.setEnabled(enabled); - mBinding.facebookPermissionFriends.setEnabled(enabled); - mBinding.facebookPermissionPhotos.setEnabled(enabled); - } - - private List getGoogleScopes() { - List result = new ArrayList<>(); - if (mBinding.googleScopeYoutubeData.isChecked()) { - result.add("https://www.googleapis.com/auth/youtube.readonly"); - } - if (mBinding.googleScopeDriveFile.isChecked()) { - result.add(Scopes.DRIVE_FILE); - } - return result; - } - - private List getFacebookPermissions() { - List result = new ArrayList<>(); - if (mBinding.facebookPermissionFriends.isChecked()) { - result.add("user_friends"); - } - if (mBinding.facebookPermissionPhotos.isChecked()) { - result.add("user_photos"); - } - return result; - } - - private void showSnackbar(@StringRes int errorMessageRes) { - Snackbar.make(mBinding.getRoot(), errorMessageRes, Snackbar.LENGTH_LONG).show(); - } - - @Override - public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) { - // Successfully signed in - IdpResponse response = result.getIdpResponse(); - handleSignInResponse(result.getResultCode(), response); - } -} diff --git a/app/src/main/java/com/firebase/uidemo/auth/SignedInActivity.java b/app/src/main/java/com/firebase/uidemo/auth/SignedInActivity.java deleted file mode 100644 index 9749f5c86..000000000 --- a/app/src/main/java/com/firebase/uidemo/auth/SignedInActivity.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2016 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.firebase.uidemo.auth; - -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.text.TextUtils; -import android.util.Log; -import android.view.View; -import android.widget.TextView; - -import com.firebase.ui.auth.AuthUI; -import com.firebase.ui.auth.IdpResponse; -import com.firebase.ui.auth.util.ExtraConstants; -import com.firebase.uidemo.R; -import com.firebase.uidemo.databinding.SignedInLayoutBinding; -import com.firebase.uidemo.storage.GlideApp; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.snackbar.Snackbar; -import com.google.firebase.auth.EmailAuthProvider; -import com.google.firebase.auth.FacebookAuthProvider; -import com.google.firebase.auth.FirebaseAuth; -import com.google.firebase.auth.FirebaseAuthProvider; -import com.google.firebase.auth.FirebaseUser; -import com.google.firebase.auth.GoogleAuthProvider; -import com.google.firebase.auth.PhoneAuthProvider; -import com.google.firebase.auth.TwitterAuthProvider; -import com.google.firebase.auth.UserInfo; - -import java.util.ArrayList; -import java.util.List; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; -import androidx.appcompat.app.AppCompatActivity; - -import static com.firebase.ui.auth.AuthUI.EMAIL_LINK_PROVIDER; - -public class SignedInActivity extends AppCompatActivity { - private static final String TAG = "SignedInActivity"; - - private SignedInLayoutBinding mBinding; - - @NonNull - public static Intent createIntent(@NonNull Context context, @Nullable IdpResponse response) { - return new Intent().setClass(context, SignedInActivity.class) - .putExtra(ExtraConstants.IDP_RESPONSE, response); - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); - if (currentUser == null) { - startActivity(AuthUiActivity.createIntent(this)); - finish(); - return; - } - - IdpResponse response = getIntent().getParcelableExtra(ExtraConstants.IDP_RESPONSE); - - mBinding = SignedInLayoutBinding.inflate(getLayoutInflater()); - setContentView(mBinding.getRoot()); - populateProfile(response); - populateIdpToken(response); - - mBinding.deleteAccount.setOnClickListener(view -> deleteAccountClicked()); - - mBinding.signOut.setOnClickListener(view -> signOut()); - } - - public void signOut() { - AuthUI.getInstance() - .signOut(this) - .addOnCompleteListener(task -> { - if (task.isSuccessful()) { - startActivity(AuthUiActivity.createIntent(SignedInActivity.this)); - finish(); - } else { - Log.w(TAG, "signOut:failure", task.getException()); - showSnackbar(R.string.sign_out_failed); - } - }); - } - - public void deleteAccountClicked() { - new MaterialAlertDialogBuilder(this) - .setMessage("Are you sure you want to delete this account?") - .setPositiveButton("Yes, nuke it!", (dialogInterface, i) -> deleteAccount()) - .setNegativeButton("No", null) - .show(); - } - - private void deleteAccount() { - AuthUI.getInstance() - .delete(this) - .addOnCompleteListener(this, task -> { - if (task.isSuccessful()) { - startActivity(AuthUiActivity.createIntent(SignedInActivity.this)); - finish(); - } else { - showSnackbar(R.string.delete_account_failed); - } - }); - } - - private void populateProfile(@Nullable IdpResponse response) { - FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); - if (user.getPhotoUrl() != null) { - GlideApp.with(this) - .load(user.getPhotoUrl()) - .fitCenter() - .into(mBinding.userProfilePicture); - } - - mBinding.userEmail.setText( - TextUtils.isEmpty(user.getEmail()) ? "No email" : user.getEmail()); - mBinding.userPhoneNumber.setText( - TextUtils.isEmpty(user.getPhoneNumber()) ? "No phone number" : user.getPhoneNumber()); - mBinding.userDisplayName.setText( - TextUtils.isEmpty(user.getDisplayName()) ? "No display name" : user.getDisplayName()); - - if (response == null) { - mBinding.userIsNew.setVisibility(View.GONE); - } else { - mBinding.userIsNew.setVisibility(View.VISIBLE); - mBinding.userIsNew.setText(response.isNewUser() ? "New user" : "Existing user"); - } - - List providers = new ArrayList<>(); - if (user.getProviderData().isEmpty()) { - providers.add(getString(R.string.providers_anonymous)); - } else { - for (UserInfo info : user.getProviderData()) { - switch (info.getProviderId()) { - case GoogleAuthProvider.PROVIDER_ID: - providers.add(getString(R.string.providers_google)); - break; - case FacebookAuthProvider.PROVIDER_ID: - providers.add(getString(R.string.providers_facebook)); - break; - case TwitterAuthProvider.PROVIDER_ID: - providers.add(getString(R.string.providers_twitter)); - break; - case EmailAuthProvider.PROVIDER_ID: - providers.add(getString(R.string.providers_email)); - break; - case PhoneAuthProvider.PROVIDER_ID: - providers.add(getString(R.string.providers_phone)); - break; - case EMAIL_LINK_PROVIDER: - providers.add(getString(R.string.providers_email_link)); - break; - case FirebaseAuthProvider.PROVIDER_ID: - // Ignore this provider, it's not very meaningful - break; - default: - providers.add(info.getProviderId()); - } - } - } - - mBinding.userEnabledProviders.setText(getString(R.string.used_providers, providers)); - } - - private void populateIdpToken(@Nullable IdpResponse response) { - String token = null; - String secret = null; - if (response != null) { - token = response.getIdpToken(); - secret = response.getIdpSecret(); - } - - View idpTokenLayout = findViewById(R.id.idp_token_layout); - if (token == null) { - idpTokenLayout.setVisibility(View.GONE); - } else { - idpTokenLayout.setVisibility(View.VISIBLE); - ((TextView) findViewById(R.id.idp_token)).setText(token); - } - - View idpSecretLayout = findViewById(R.id.idp_secret_layout); - if (secret == null) { - idpSecretLayout.setVisibility(View.GONE); - } else { - idpSecretLayout.setVisibility(View.VISIBLE); - ((TextView) findViewById(R.id.idp_secret)).setText(secret); - } - } - - private void showSnackbar(@StringRes int errorMessageRes) { - Snackbar.make(mBinding.getRoot(), errorMessageRes, Snackbar.LENGTH_LONG).show(); - } -} diff --git a/app/src/main/java/com/firebase/uidemo/database/AbstractChat.java b/app/src/main/java/com/firebase/uidemo/database/AbstractChat.java deleted file mode 100644 index 447abd197..000000000 --- a/app/src/main/java/com/firebase/uidemo/database/AbstractChat.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.firebase.uidemo.database; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * Common interface for chat messages, helps share code between RTDB and Firestore examples. - */ -public abstract class AbstractChat { - - @Nullable - public abstract String getName(); - - public abstract void setName(@Nullable String name); - - @Nullable - public abstract String getMessage(); - - public abstract void setMessage(@Nullable String message); - - @NonNull - public abstract String getUid(); - - public abstract void setUid(@NonNull String uid); - - @Override - public abstract boolean equals(@Nullable Object obj); - - @Override - public abstract int hashCode(); - -} diff --git a/app/src/main/java/com/firebase/uidemo/database/ChatHolder.java b/app/src/main/java/com/firebase/uidemo/database/ChatHolder.java deleted file mode 100644 index b783415c5..000000000 --- a/app/src/main/java/com/firebase/uidemo/database/ChatHolder.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.firebase.uidemo.database; - -import android.graphics.PorterDuff; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.RotateDrawable; -import android.view.Gravity; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import com.firebase.uidemo.R; -import com.google.firebase.auth.FirebaseAuth; -import com.google.firebase.auth.FirebaseUser; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.recyclerview.widget.RecyclerView; - -public class ChatHolder extends RecyclerView.ViewHolder { - private final TextView mNameField; - private final TextView mTextField; - private final FrameLayout mLeftArrow; - private final FrameLayout mRightArrow; - private final RelativeLayout mMessageContainer; - private final LinearLayout mMessage; - private final int mGreen300; - private final int mGray300; - - public ChatHolder(@NonNull View itemView) { - super(itemView); - mNameField = itemView.findViewById(R.id.name_text); - mTextField = itemView.findViewById(R.id.message_text); - mLeftArrow = itemView.findViewById(R.id.left_arrow); - mRightArrow = itemView.findViewById(R.id.right_arrow); - mMessageContainer = itemView.findViewById(R.id.message_container); - mMessage = itemView.findViewById(R.id.message); - mGreen300 = ContextCompat.getColor(itemView.getContext(), R.color.material_green_300); - mGray300 = ContextCompat.getColor(itemView.getContext(), R.color.material_gray_300); - } - - public void bind(@NonNull AbstractChat chat) { - setName(chat.getName()); - setMessage(chat.getMessage()); - - FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); - setIsSender(currentUser != null && chat.getUid().equals(currentUser.getUid())); - } - - private void setName(@Nullable String name) { - mNameField.setText(name); - } - - private void setMessage(@Nullable String text) { - mTextField.setText(text); - } - - private void setIsSender(boolean isSender) { - final int color; - if (isSender) { - color = mGreen300; - mLeftArrow.setVisibility(View.GONE); - mRightArrow.setVisibility(View.VISIBLE); - mMessageContainer.setGravity(Gravity.END); - } else { - color = mGray300; - mLeftArrow.setVisibility(View.VISIBLE); - mRightArrow.setVisibility(View.GONE); - mMessageContainer.setGravity(Gravity.START); - } - - ((GradientDrawable) mMessage.getBackground()).setColor(color); - ((RotateDrawable) mLeftArrow.getBackground()).getDrawable() - .setColorFilter(color, PorterDuff.Mode.SRC); - ((RotateDrawable) mRightArrow.getBackground()).getDrawable() - .setColorFilter(color, PorterDuff.Mode.SRC); - } -} diff --git a/app/src/main/java/com/firebase/uidemo/database/firestore/Chat.java b/app/src/main/java/com/firebase/uidemo/database/firestore/Chat.java deleted file mode 100644 index ef95a90ed..000000000 --- a/app/src/main/java/com/firebase/uidemo/database/firestore/Chat.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.firebase.uidemo.database.firestore; - -import com.firebase.uidemo.database.AbstractChat; -import com.google.firebase.firestore.IgnoreExtraProperties; -import com.google.firebase.firestore.ServerTimestamp; - -import java.util.Date; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -@IgnoreExtraProperties -public class Chat extends AbstractChat { - private String mName; - private String mMessage; - private String mUid; - private Date mTimestamp; - - public Chat() { - // Needed for Firebase - } - - public Chat(@Nullable String name, @Nullable String message, @NonNull String uid) { - mName = name; - mMessage = message; - mUid = uid; - } - - @Override - @Nullable - public String getName() { - return mName; - } - - @Override - public void setName(@Nullable String name) { - mName = name; - } - - @Override - @Nullable - public String getMessage() { - return mMessage; - } - - @Override - public void setMessage(@Nullable String message) { - mMessage = message; - } - - @Override - @NonNull - public String getUid() { - return mUid; - } - - @Override - public void setUid(@NonNull String uid) { - mUid = uid; - } - - @ServerTimestamp - @Nullable - public Date getTimestamp() { - return mTimestamp; - } - - public void setTimestamp(@Nullable Date timestamp) { - mTimestamp = timestamp; - } - - @Override - public boolean equals(@Nullable Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Chat chat = (Chat) o; - - return mTimestamp.equals(chat.mTimestamp) - && mUid.equals(chat.mUid) - && (mName == null ? chat.mName == null : mName.equals(chat.mName)) - && (mMessage == null ? chat.mMessage == null : mMessage.equals(chat.mMessage)); - } - - @Override - public int hashCode() { - int result = mName == null ? 0 : mName.hashCode(); - result = 31 * result + (mMessage == null ? 0 : mMessage.hashCode()); - result = 31 * result + mUid.hashCode(); - result = 31 * result + mTimestamp.hashCode(); - return result; - } - - @NonNull - @Override - public String toString() { - return "Chat{" + - "mName='" + mName + '\'' + - ", mMessage='" + mMessage + '\'' + - ", mUid='" + mUid + '\'' + - ", mTimestamp=" + mTimestamp + - '}'; - } -} diff --git a/app/src/main/java/com/firebase/uidemo/database/firestore/FirestoreChatActivity.java b/app/src/main/java/com/firebase/uidemo/database/firestore/FirestoreChatActivity.java deleted file mode 100644 index 59af0408b..000000000 --- a/app/src/main/java/com/firebase/uidemo/database/firestore/FirestoreChatActivity.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.firebase.uidemo.database.firestore; - -import android.annotation.SuppressLint; -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Toast; - -import com.firebase.ui.auth.util.ui.ImeHelper; -import com.firebase.ui.firestore.FirestoreRecyclerAdapter; -import com.firebase.ui.firestore.FirestoreRecyclerOptions; -import com.firebase.uidemo.R; -import com.firebase.uidemo.database.ChatHolder; -import com.firebase.uidemo.databinding.ActivityChatBinding; -import com.firebase.uidemo.util.SignInResultNotifier; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.firebase.auth.FirebaseAuth; -import com.google.firebase.firestore.CollectionReference; -import com.google.firebase.firestore.FirebaseFirestore; -import com.google.firebase.firestore.Query; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -/** - * Class demonstrating how to setup a {@link RecyclerView} with an adapter while taking sign-in - * states into consideration. Also demonstrates adding data to a ref and then reading it back using - * the {@link FirestoreRecyclerAdapter} to build a simple chat app. - *

- * For a general intro to the RecyclerView, see Creating - * Lists. - */ -@SuppressLint("RestrictedApi") -public class FirestoreChatActivity extends AppCompatActivity - implements FirebaseAuth.AuthStateListener { - private static final String TAG = "FirestoreChatActivity"; - - private static final CollectionReference sChatCollection = - FirebaseFirestore.getInstance().collection("chats"); - /** Get the last 50 chat messages ordered by timestamp . */ - private static final Query sChatQuery = - sChatCollection.orderBy("timestamp", Query.Direction.DESCENDING).limit(50); - - static { - FirebaseFirestore.setLoggingEnabled(true); - } - - private ActivityChatBinding mBinding; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mBinding = ActivityChatBinding.inflate(getLayoutInflater()); - setContentView(mBinding.getRoot()); - - LinearLayoutManager manager = new LinearLayoutManager(this); - manager.setReverseLayout(true); - manager.setStackFromEnd(true); - - mBinding.messagesList.setHasFixedSize(true); - mBinding.messagesList.setLayoutManager(manager); - - mBinding.messagesList.addOnLayoutChangeListener((view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - if (bottom < oldBottom) { - mBinding.messagesList.postDelayed(() -> mBinding.messagesList.smoothScrollToPosition( - 0), 100); - } - }); - - ImeHelper.setImeOnDoneListener(mBinding.messageEdit, () -> onSendClick()); - - mBinding.sendButton.setOnClickListener(view -> onSendClick()); - } - - @Override - public void onStart() { - super.onStart(); - if (isSignedIn()) { - attachRecyclerViewAdapter(); - } - FirebaseAuth.getInstance().addAuthStateListener(this); - } - - @Override - protected void onStop() { - super.onStop(); - FirebaseAuth.getInstance().removeAuthStateListener(this); - } - - @Override - public void onAuthStateChanged(@NonNull FirebaseAuth auth) { - mBinding.sendButton.setEnabled(isSignedIn()); - mBinding.messageEdit.setEnabled(isSignedIn()); - - if (isSignedIn()) { - attachRecyclerViewAdapter(); - } else { - Toast.makeText(this, R.string.signing_in, Toast.LENGTH_SHORT).show(); - auth.signInAnonymously().addOnCompleteListener(new SignInResultNotifier(this)); - } - } - - private boolean isSignedIn() { - return FirebaseAuth.getInstance().getCurrentUser() != null; - } - - private void attachRecyclerViewAdapter() { - final RecyclerView.Adapter adapter = newAdapter(); - - // Scroll to bottom on new messages - adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { - @Override - public void onItemRangeInserted(int positionStart, int itemCount) { - mBinding.messagesList.smoothScrollToPosition(0); - } - }); - - mBinding.messagesList.setAdapter(adapter); - } - - public void onSendClick() { - String uid = FirebaseAuth.getInstance().getCurrentUser().getUid(); - String name = "User " + uid.substring(0, 6); - - onAddMessage(new Chat(name, mBinding.messageEdit.getText().toString(), uid)); - - mBinding.messageEdit.setText(""); - } - - @NonNull - private RecyclerView.Adapter newAdapter() { - FirestoreRecyclerOptions options = - new FirestoreRecyclerOptions.Builder() - .setQuery(sChatQuery, Chat.class) - .setLifecycleOwner(this) - .build(); - - return new FirestoreRecyclerAdapter(options) { - @NonNull - @Override - public ChatHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new ChatHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.message, parent, false)); - } - - @Override - protected void onBindViewHolder(@NonNull ChatHolder holder, int position, @NonNull Chat model) { - holder.bind(model); - } - - @Override - public void onDataChanged() { - // If there are no chat messages, show a view that invites the user to add a message. - mBinding.emptyTextView.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE); - } - }; - } - - private void onAddMessage(@NonNull Chat chat) { - sChatCollection.add(chat).addOnFailureListener(this, - e -> Log.e(TAG, "Failed to write message", e)); - } -} diff --git a/app/src/main/java/com/firebase/uidemo/database/firestore/FirestorePagingActivity.java b/app/src/main/java/com/firebase/uidemo/database/firestore/FirestorePagingActivity.java deleted file mode 100644 index 6563ef410..000000000 --- a/app/src/main/java/com/firebase/uidemo/database/firestore/FirestorePagingActivity.java +++ /dev/null @@ -1,200 +0,0 @@ -package com.firebase.uidemo.database.firestore; - -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import android.widget.Toast; - -import com.firebase.ui.firestore.paging.FirestorePagingAdapter; -import com.firebase.ui.firestore.paging.FirestorePagingOptions; -import com.firebase.uidemo.R; -import com.firebase.uidemo.databinding.ActivityFirestorePagingBinding; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.firestore.CollectionReference; -import com.google.firebase.firestore.FirebaseFirestore; -import com.google.firebase.firestore.Query; -import com.google.firebase.firestore.WriteBatch; - -import java.util.Locale; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.paging.CombinedLoadStates; -import androidx.paging.LoadState; -import androidx.paging.PagingConfig; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import kotlin.Unit; -import kotlin.jvm.functions.Function1; - -public class FirestorePagingActivity extends AppCompatActivity { - - private static final String TAG = "FirestorePagingActivity"; - - private ActivityFirestorePagingBinding mBinding; - - private FirebaseFirestore mFirestore; - private CollectionReference mItemsCollection; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mBinding = ActivityFirestorePagingBinding.inflate(getLayoutInflater()); - setContentView(mBinding.getRoot()); - - mFirestore = FirebaseFirestore.getInstance(); - mItemsCollection = mFirestore.collection("items"); - - setUpAdapter(); - } - - private void setUpAdapter() { - Query baseQuery = mItemsCollection.orderBy("value", Query.Direction.ASCENDING); - - PagingConfig config = new PagingConfig(20, 10, false); - - FirestorePagingOptions options = new FirestorePagingOptions.Builder() - .setLifecycleOwner(this) - .setQuery(baseQuery, config, Item.class) - .build(); - - final FirestorePagingAdapter adapter = - new FirestorePagingAdapter(options) { - @NonNull - @Override - public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, - int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_item, parent, false); - return new ItemViewHolder(view); - } - - @Override - protected void onBindViewHolder(@NonNull ItemViewHolder holder, - int position, - @NonNull Item model) { - holder.bind(model); - } - }; - adapter.addLoadStateListener(states -> { - LoadState refresh = states.getRefresh(); - LoadState append = states.getAppend(); - - if (refresh instanceof LoadState.Error || append instanceof LoadState.Error) { - showToast("An error occurred."); - adapter.retry(); - } - - if (append instanceof LoadState.Loading) { - mBinding.swipeRefreshLayout.setRefreshing(true); - } - - if (append instanceof LoadState.NotLoading) { - LoadState.NotLoading notLoading = (LoadState.NotLoading) append; - if (notLoading.getEndOfPaginationReached()) { - // This indicates that the user has scrolled - // until the end of the data set. - mBinding.swipeRefreshLayout.setRefreshing(false); - showToast("Reached end of data set."); - return null; - } - - if (refresh instanceof LoadState.NotLoading) { - // This indicates the most recent load - // has finished. - mBinding.swipeRefreshLayout.setRefreshing(false); - return null; - } - } - return null; - }); - - mBinding.pagingRecycler.setLayoutManager(new LinearLayoutManager(this)); - mBinding.pagingRecycler.setAdapter(adapter); - - mBinding.swipeRefreshLayout.setOnRefreshListener(() -> adapter.refresh()); - } - - @Override - public boolean onCreateOptionsMenu(@NonNull Menu menu) { - getMenuInflater().inflate(R.menu.menu_paging, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.item_add_data) { - showToast("Adding data..."); - createItems().addOnCompleteListener(this, task -> { - if (task.isSuccessful()) { - showToast("Data added."); - } else { - Log.w(TAG, "addData", task.getException()); - showToast("Error adding data."); - } - }); - - return true; - } - return super.onOptionsItemSelected(item); - } - - @NonNull - private Task createItems() { - WriteBatch writeBatch = mFirestore.batch(); - - for (int i = 0; i < 250; i++) { - String title = "Item " + i; - - String id = String.format(Locale.getDefault(), "item_%03d", i); - Item item = new Item(title, i); - - writeBatch.set(mItemsCollection.document(id), item); - } - - return writeBatch.commit(); - } - - private void showToast(@NonNull String message) { - Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); - } - - public static class Item { - - @Nullable public String text; - public int value; - - public Item() {} - - public Item(@Nullable String text, int value) { - this.text = text; - this.value = value; - } - - } - - public static class ItemViewHolder extends RecyclerView.ViewHolder { - TextView mTextView; - TextView mValueView; - - ItemViewHolder(@NonNull View itemView) { - super(itemView); - mTextView = itemView.findViewById(R.id.item_text); - mValueView = itemView.findViewById(R.id.item_value); - } - - void bind(@NonNull Item item) { - mTextView.setText(item.text); - mValueView.setText(String.valueOf(item.value)); - } - } - -} diff --git a/app/src/main/java/com/firebase/uidemo/database/realtime/Chat.java b/app/src/main/java/com/firebase/uidemo/database/realtime/Chat.java deleted file mode 100644 index 55361adbc..000000000 --- a/app/src/main/java/com/firebase/uidemo/database/realtime/Chat.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.firebase.uidemo.database.realtime; - -import com.firebase.uidemo.database.AbstractChat; -import com.google.firebase.database.IgnoreExtraProperties; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -@IgnoreExtraProperties -public class Chat extends AbstractChat { - private String mName; - private String mMessage; - private String mUid; - - public Chat() { - // Needed for Firebase - } - - public Chat(@Nullable String name, @Nullable String message, @NonNull String uid) { - mName = name; - mMessage = message; - mUid = uid; - } - - @Override - @Nullable - public String getName() { - return mName; - } - - public void setName(@Nullable String name) { - mName = name; - } - - @Override - @Nullable - public String getMessage() { - return mMessage; - } - - public void setMessage(@Nullable String message) { - mMessage = message; - } - - @Override - @NonNull - public String getUid() { - return mUid; - } - - public void setUid(@NonNull String uid) { - mUid = uid; - } - - @Override - public boolean equals(@Nullable Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Chat chat = (Chat) o; - - return mUid.equals(chat.mUid) - && (mName == null ? chat.mName == null : mName.equals(chat.mName)) - && (mMessage == null ? chat.mMessage == null : mMessage.equals(chat.mMessage)); - } - - @Override - public int hashCode() { - int result = mName == null ? 0 : mName.hashCode(); - result = 31 * result + (mMessage == null ? 0 : mMessage.hashCode()); - result = 31 * result + mUid.hashCode(); - return result; - } - - @Override - @NonNull - public String toString() { - return "Chat{" + - "mName='" + mName + '\'' + - ", mMessage='" + mMessage + '\'' + - ", mUid='" + mUid + '\'' + - '}'; - } -} diff --git a/app/src/main/java/com/firebase/uidemo/database/realtime/FirebaseDbPagingActivity.java b/app/src/main/java/com/firebase/uidemo/database/realtime/FirebaseDbPagingActivity.java deleted file mode 100644 index 7c6aab3da..000000000 --- a/app/src/main/java/com/firebase/uidemo/database/realtime/FirebaseDbPagingActivity.java +++ /dev/null @@ -1,197 +0,0 @@ -package com.firebase.uidemo.database.realtime; - -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import android.widget.Toast; - -import com.firebase.ui.database.paging.DatabasePagingOptions; -import com.firebase.ui.database.paging.FirebaseRecyclerPagingAdapter; -import com.firebase.uidemo.R; -import com.firebase.uidemo.databinding.ActivityDatabasePagingBinding; -import com.google.firebase.database.FirebaseDatabase; -import com.google.firebase.database.Query; - -import java.util.Locale; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.paging.LoadState; -import androidx.paging.PagingConfig; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -public class FirebaseDbPagingActivity extends AppCompatActivity { - - private static final String TAG = "PagingActivity"; - - private ActivityDatabasePagingBinding mBinding; - - private FirebaseDatabase mDatabase; - private Query mQuery; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mBinding = ActivityDatabasePagingBinding.inflate(getLayoutInflater()); - setContentView(mBinding.getRoot()); - - mDatabase = FirebaseDatabase.getInstance(); - mQuery = mDatabase.getReference().child("items"); - - setUpAdapter(); - } - - private void setUpAdapter() { - - //Initialize Paging Configurations - PagingConfig config = new PagingConfig(30, 5, false); - - //Initialize Firebase Paging Options - DatabasePagingOptions options = new DatabasePagingOptions.Builder() - .setLifecycleOwner(this) - .setQuery(mQuery, config, Item.class) - .build(); - - //Initializing Adapter - final FirebaseRecyclerPagingAdapter mAdapter = - new FirebaseRecyclerPagingAdapter(options) { - @NonNull - @Override - public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, - int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_item, parent, false); - return new ItemViewHolder(view); - } - - @Override - protected void onBindViewHolder(@NonNull ItemViewHolder holder, - int position, - @NonNull Item model) { - holder.bind(model); - } - }; - - mAdapter.addLoadStateListener(states -> { - LoadState refresh = states.getRefresh(); - LoadState append = states.getAppend(); - - if (refresh instanceof LoadState.Error) { - LoadState.Error loadStateError = (LoadState.Error) refresh; - mBinding.swipeRefreshLayout.setRefreshing(false); - Log.e(TAG, loadStateError.getError().getLocalizedMessage()); - } - if (append instanceof LoadState.Error) { - LoadState.Error loadStateError = (LoadState.Error) append; - mBinding.swipeRefreshLayout.setRefreshing(false); - Log.e(TAG, loadStateError.getError().getLocalizedMessage()); - } - - if (append instanceof LoadState.Loading) { - mBinding.swipeRefreshLayout.setRefreshing(true); - } - - if (append instanceof LoadState.NotLoading) { - LoadState.NotLoading notLoading = (LoadState.NotLoading) append; - if (notLoading.getEndOfPaginationReached()) { - // This indicates that the user has scrolled - // until the end of the data set. - mBinding.swipeRefreshLayout.setRefreshing(false); - showToast("Reached end of data set."); - return null; - } - - if (refresh instanceof LoadState.NotLoading) { - // This indicates the most recent load - // has finished. - mBinding.swipeRefreshLayout.setRefreshing(false); - return null; - } - } - return null; - }); - - mBinding.pagingRecycler.setLayoutManager(new LinearLayoutManager(this)); - mBinding.pagingRecycler.setAdapter(mAdapter); - - // Reload data on swipe - mBinding.swipeRefreshLayout.setOnRefreshListener(() -> { - //Reload Data - mAdapter.refresh(); - }); - } - - - @Override - public boolean onCreateOptionsMenu(@NonNull Menu menu) { - getMenuInflater().inflate(R.menu.menu_paging, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.item_add_data) { - showToast("Adding data..."); - createItems(); - return true; - } - return super.onOptionsItemSelected(item); - } - - @NonNull - private void createItems() { - for (int i = 0; i < 250; i++) { - String title = "Item " + i; - - String id = String.format(Locale.getDefault(), "item_%03d", i); - Item item = new Item(title, i); - - mDatabase.getReference("items").child(id).setValue(item); - } - } - - private void showToast(@NonNull String message) { - Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); - } - - - public static class Item { - - @Nullable - public String text; - public int value; - - public Item(){} - - public Item(@Nullable String text, int value) { - this.text = text; - this.value = value; - } - } - - public static class ItemViewHolder extends RecyclerView.ViewHolder { - - TextView mTextView; - TextView mValueView; - - ItemViewHolder(@NonNull View itemView) { - super(itemView); - mTextView = itemView.findViewById(R.id.item_text); - mValueView = itemView.findViewById(R.id.item_value); - } - - void bind(@NonNull Item item) { - mTextView.setText(item.text); - mValueView.setText(String.valueOf(item.value)); - } - } - -} diff --git a/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatActivity.java b/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatActivity.java deleted file mode 100644 index 381893f7c..000000000 --- a/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatActivity.java +++ /dev/null @@ -1,156 +0,0 @@ -package com.firebase.uidemo.database.realtime; - -import android.annotation.SuppressLint; -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Toast; - -import com.firebase.ui.auth.util.ui.ImeHelper; -import com.firebase.ui.database.FirebaseRecyclerAdapter; -import com.firebase.ui.database.FirebaseRecyclerOptions; -import com.firebase.uidemo.R; -import com.firebase.uidemo.database.ChatHolder; -import com.firebase.uidemo.databinding.ActivityChatBinding; -import com.firebase.uidemo.util.SignInResultNotifier; -import com.google.firebase.auth.FirebaseAuth; -import com.google.firebase.database.DatabaseError; -import com.google.firebase.database.DatabaseReference; -import com.google.firebase.database.FirebaseDatabase; -import com.google.firebase.database.Query; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -/** - * Class demonstrating how to setup a {@link RecyclerView} with an adapter while taking sign-in - * states into consideration. Also demonstrates adding data to a ref and then reading it back using - * the {@link FirebaseRecyclerAdapter} to build a simple chat app. - *

- * For a general intro to the RecyclerView, see Creating - * Lists. - */ -@SuppressLint("RestrictedApi") -public class RealtimeDbChatActivity extends AppCompatActivity - implements FirebaseAuth.AuthStateListener { - private static final String TAG = "RealtimeDatabaseDemo"; - - /** - * Get the last 50 chat messages. - */ - @NonNull - protected final Query sChatQuery = - FirebaseDatabase.getInstance().getReference().child("chats").limitToLast(50); - - private ActivityChatBinding mBinding; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mBinding = ActivityChatBinding.inflate(getLayoutInflater()); - setContentView(mBinding.getRoot()); - - mBinding.messagesList.setHasFixedSize(true); - mBinding.messagesList.setLayoutManager(new LinearLayoutManager(this)); - - ImeHelper.setImeOnDoneListener(mBinding.messageEdit, () -> onSendClick()); - - mBinding.sendButton.setOnClickListener(view -> onSendClick()); - } - - @Override - public void onStart() { - super.onStart(); - if (isSignedIn()) { - attachRecyclerViewAdapter(); - } - FirebaseAuth.getInstance().addAuthStateListener(this); - } - - @Override - protected void onStop() { - super.onStop(); - FirebaseAuth.getInstance().removeAuthStateListener(this); - } - - @Override - public void onAuthStateChanged(@NonNull FirebaseAuth auth) { - mBinding.sendButton.setEnabled(isSignedIn()); - mBinding.messageEdit.setEnabled(isSignedIn()); - - if (isSignedIn()) { - attachRecyclerViewAdapter(); - } else { - Toast.makeText(this, R.string.signing_in, Toast.LENGTH_SHORT).show(); - auth.signInAnonymously().addOnCompleteListener(new SignInResultNotifier(this)); - } - } - - private boolean isSignedIn() { - return FirebaseAuth.getInstance().getCurrentUser() != null; - } - - private void attachRecyclerViewAdapter() { - final RecyclerView.Adapter adapter = newAdapter(); - - // Scroll to bottom on new messages - adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { - @Override - public void onItemRangeInserted(int positionStart, int itemCount) { - mBinding.messagesList.smoothScrollToPosition(adapter.getItemCount()); - } - }); - - mBinding.messagesList.setAdapter(adapter); - } - - public void onSendClick() { - String uid = FirebaseAuth.getInstance().getCurrentUser().getUid(); - String name = "User " + uid.substring(0, 6); - - onAddMessage(new Chat(name, mBinding.messageEdit.getText().toString(), uid)); - - mBinding.messageEdit.setText(""); - } - - @NonNull - protected RecyclerView.Adapter newAdapter() { - FirebaseRecyclerOptions options = - new FirebaseRecyclerOptions.Builder() - .setQuery(sChatQuery, Chat.class) - .setLifecycleOwner(this) - .build(); - - return new FirebaseRecyclerAdapter(options) { - @Override - public ChatHolder onCreateViewHolder(ViewGroup parent, int viewType) { - return new ChatHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.message, parent, false)); - } - - @Override - protected void onBindViewHolder(@NonNull ChatHolder holder, int position, @NonNull Chat model) { - holder.bind(model); - } - - @Override - public void onDataChanged() { - // If there are no chat messages, show a view that invites the user to add a message. - mBinding.emptyTextView.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE); - } - }; - } - - protected void onAddMessage(@NonNull Chat chat) { - sChatQuery.getRef().push().setValue(chat, (error, reference) -> { - if (error != null) { - Log.e(TAG, "Failed to write message", error.toException()); - } - }); - } -} diff --git a/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatIndexActivity.java b/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatIndexActivity.java deleted file mode 100644 index c55b2cd24..000000000 --- a/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatIndexActivity.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.firebase.uidemo.database.realtime; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.firebase.ui.database.FirebaseRecyclerAdapter; -import com.firebase.ui.database.FirebaseRecyclerOptions; -import com.firebase.uidemo.R; -import com.firebase.uidemo.database.ChatHolder; -import com.google.firebase.auth.FirebaseAuth; -import com.google.firebase.database.DatabaseReference; -import com.google.firebase.database.FirebaseDatabase; - -import androidx.annotation.NonNull; - -public class RealtimeDbChatIndexActivity extends RealtimeDbChatActivity { - private DatabaseReference mChatIndicesRef; - - @NonNull - @Override - protected FirebaseRecyclerAdapter newAdapter() { - mChatIndicesRef = FirebaseDatabase.getInstance() - .getReference() - .child("chatIndices") - .child(FirebaseAuth.getInstance().getCurrentUser().getUid()); - - FirebaseRecyclerOptions options = - new FirebaseRecyclerOptions.Builder() - .setIndexedQuery( - mChatIndicesRef.limitToFirst(50), sChatQuery.getRef(), Chat.class) - .setLifecycleOwner(this) - .build(); - - return new FirebaseRecyclerAdapter(options) { - @NonNull - @Override - public ChatHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new ChatHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.message, parent, false)); - } - - @Override - protected void onBindViewHolder(@NonNull ChatHolder holder, int position, @NonNull Chat model) { - holder.bind(model); - } - - @Override - public void onDataChanged() { - // If there are no chat messages, show a view that invites the user to add a message. - findViewById(R.id.emptyTextView).setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE); - } - }; - } - - @Override - protected void onAddMessage(@NonNull Chat chat) { - DatabaseReference chatRef = sChatQuery.getRef().push(); - mChatIndicesRef.child(chatRef.getKey()).setValue(true); - chatRef.setValue(chat); - } -} diff --git a/app/src/main/java/com/firebase/uidemo/storage/ImageActivity.java b/app/src/main/java/com/firebase/uidemo/storage/ImageActivity.java deleted file mode 100644 index bf2f57a80..000000000 --- a/app/src/main/java/com/firebase/uidemo/storage/ImageActivity.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.firebase.uidemo.storage; - -import android.Manifest; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.provider.MediaStore; -import android.util.Log; -import android.view.View; -import android.widget.Toast; - -import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; -import com.firebase.uidemo.BuildConfig; -import com.firebase.uidemo.R; -import com.firebase.uidemo.databinding.ActivityImageBinding; -import com.firebase.uidemo.util.SignInResultNotifier; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; -import com.google.firebase.auth.FirebaseAuth; -import com.google.firebase.storage.FirebaseStorage; -import com.google.firebase.storage.StorageReference; -import com.google.firebase.storage.UploadTask; - -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import pub.devrel.easypermissions.AfterPermissionGranted; -import pub.devrel.easypermissions.AppSettingsDialog; -import pub.devrel.easypermissions.EasyPermissions; - -public class ImageActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { - - private static final String TAG = "ImageDemo"; - private static final int RC_CHOOSE_PHOTO = 101; - private static final int RC_IMAGE_PERMS = 102; - private static final String PERMS = Manifest.permission.READ_EXTERNAL_STORAGE; - - private StorageReference mImageRef; - - private ActivityImageBinding mBinding; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mBinding = ActivityImageBinding.inflate(getLayoutInflater()); - setContentView(mBinding.getRoot()); - - mBinding.buttonDownloadDirect.setOnClickListener(view -> { - // Download directly from StorageReference using Glide - // (See MyAppGlideModule for Loader registration) - GlideApp.with(ImageActivity.this) - .load(mImageRef) - .centerCrop() - .transition(DrawableTransitionOptions.withCrossFade()) - .into(mBinding.firstImage); - }); - - mBinding.buttonChoosePhoto.setOnClickListener(view -> choosePhoto()); - - // By default, Cloud Storage files require authentication to read or write. - // For this sample to function correctly, enable Anonymous Auth in the Firebase console: - // https://console.firebase.google.com/project/_/authentication/providers - FirebaseAuth.getInstance() - .signInAnonymously() - .addOnCompleteListener(new SignInResultNotifier(this)); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - if (requestCode == RC_CHOOSE_PHOTO) { - if (resultCode == RESULT_OK) { - Uri selectedImage = data.getData(); - uploadPhoto(selectedImage); - } else { - Toast.makeText(this, "No image chosen", Toast.LENGTH_SHORT).show(); - } - } else if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE - && EasyPermissions.hasPermissions(this, PERMS)) { - choosePhoto(); - } - } - - @AfterPermissionGranted(RC_IMAGE_PERMS) - protected void choosePhoto() { - if (!EasyPermissions.hasPermissions(this, PERMS)) { - EasyPermissions.requestPermissions(this, getString(R.string.rational_image_perm), - RC_IMAGE_PERMS, PERMS); - return; - } - - Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); - startActivityForResult(i, RC_CHOOSE_PHOTO); - } - - private void uploadPhoto(Uri uri) { - // Reset UI - hideDownloadUI(); - Toast.makeText(this, "Uploading...", Toast.LENGTH_SHORT).show(); - - // Upload to Cloud Storage - String uuid = UUID.randomUUID().toString(); - mImageRef = FirebaseStorage.getInstance().getReference(uuid); - mImageRef.putFile(uri) - .addOnSuccessListener(this, taskSnapshot -> { - if (BuildConfig.DEBUG) { - Log.d(TAG, "uploadPhoto:onSuccess:" + - taskSnapshot.getMetadata().getReference().getPath()); - } - Toast.makeText(ImageActivity.this, "Image uploaded", - Toast.LENGTH_SHORT).show(); - - showDownloadUI(); - }) - .addOnFailureListener(this, e -> { - Log.w(TAG, "uploadPhoto:onError", e); - Toast.makeText(ImageActivity.this, "Upload failed", - Toast.LENGTH_SHORT).show(); - }); - } - - private void hideDownloadUI() { - mBinding.buttonDownloadDirect.setEnabled(false); - - mBinding.firstImage.setImageResource(0); - mBinding.firstImage.setVisibility(View.INVISIBLE); - } - - private void showDownloadUI() { - mBinding.buttonDownloadDirect.setEnabled(true); - - mBinding.firstImage.setVisibility(View.VISIBLE); - } - - @Override - public void onRequestPermissionsResult(int requestCode, - @NonNull String[] permissions, - @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); - } - - @Override - public void onPermissionsGranted(int requestCode, @NonNull List perms) { - // See #choosePhoto with @AfterPermissionGranted - } - - @Override - public void onPermissionsDenied(int requestCode, @NonNull List perms) { - if (EasyPermissions.somePermissionPermanentlyDenied(this, - Collections.singletonList(PERMS))) { - new AppSettingsDialog.Builder(this).build().show(); - } - } -} diff --git a/app/src/main/java/com/firebase/uidemo/storage/MyAppGlideModule.java b/app/src/main/java/com/firebase/uidemo/storage/MyAppGlideModule.java deleted file mode 100644 index bc1f11568..000000000 --- a/app/src/main/java/com/firebase/uidemo/storage/MyAppGlideModule.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.firebase.uidemo.storage; - -import android.content.Context; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.Registry; -import com.bumptech.glide.annotation.GlideModule; -import com.bumptech.glide.module.AppGlideModule; -import com.firebase.ui.storage.images.FirebaseImageLoader; -import com.google.firebase.storage.StorageReference; - -import java.io.InputStream; - -import androidx.annotation.NonNull; - -/** - * Glide module to register {@link com.firebase.ui.storage.images.FirebaseImageLoader}. - * See: http://bumptech.github.io/glide/doc/generatedapi.html - */ -@GlideModule -public class MyAppGlideModule extends AppGlideModule { - - @Override - public void registerComponents(@NonNull Context context, - @NonNull Glide glide, - @NonNull Registry registry) { - // Register FirebaseImageLoader to handle StorageReference - registry.append(StorageReference.class, InputStream.class, - new FirebaseImageLoader.Factory()); - } - -} diff --git a/app/src/main/java/com/firebase/uidemo/util/ConfigurationUtils.java b/app/src/main/java/com/firebase/uidemo/util/ConfigurationUtils.java deleted file mode 100644 index bb7545bdf..000000000 --- a/app/src/main/java/com/firebase/uidemo/util/ConfigurationUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.firebase.uidemo.util; - -import android.annotation.SuppressLint; -import android.content.Context; - -import com.firebase.ui.auth.AuthUI; -import com.firebase.uidemo.R; -import com.google.firebase.auth.ActionCodeSettings; - -import java.util.ArrayList; -import java.util.List; - -import androidx.annotation.NonNull; - -@SuppressLint("RestrictedApi") -public final class ConfigurationUtils { - - private ConfigurationUtils() { - throw new AssertionError("No instance for you!"); - } - - public static boolean isGoogleMisconfigured(@NonNull Context context) { - return AuthUI.UNCONFIGURED_CONFIG_VALUE.equals( - context.getString(R.string.default_web_client_id)); - } - - public static boolean isFacebookMisconfigured(@NonNull Context context) { - return AuthUI.UNCONFIGURED_CONFIG_VALUE.equals( - context.getString(R.string.facebook_application_id)); - } - - @NonNull - public static List getConfiguredProviders(@NonNull Context context) { - List providers = new ArrayList<>(); - - if (!isGoogleMisconfigured(context)) { - providers.add(new AuthUI.IdpConfig.GoogleBuilder().build()); - } - - if (!isFacebookMisconfigured(context)) { - providers.add(new AuthUI.IdpConfig.FacebookBuilder().build()); - } - - ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder() - .setAndroidPackageName("com.firebase.uidemo", true, null) - .setHandleCodeInApp(true) - .setUrl("https://google.com") - .build(); - - providers.add(new AuthUI.IdpConfig.EmailBuilder() - .setAllowNewAccounts(true) - .enableEmailLinkSignIn() - .setActionCodeSettings(actionCodeSettings) - .build()); - - providers.add(new AuthUI.IdpConfig.TwitterBuilder().build()); - providers.add(new AuthUI.IdpConfig.PhoneBuilder().build()); - providers.add(new AuthUI.IdpConfig.MicrosoftBuilder().build()); - providers.add(new AuthUI.IdpConfig.YahooBuilder().build()); - providers.add(new AuthUI.IdpConfig.AppleBuilder().build()); - - return providers; - } -} diff --git a/app/src/main/java/com/firebase/uidemo/util/SignInResultNotifier.java b/app/src/main/java/com/firebase/uidemo/util/SignInResultNotifier.java deleted file mode 100644 index ec3d96f0e..000000000 --- a/app/src/main/java/com/firebase/uidemo/util/SignInResultNotifier.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.firebase.uidemo.util; - -import android.content.Context; -import android.widget.Toast; - -import com.firebase.uidemo.R; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.auth.AuthResult; - -import androidx.annotation.NonNull; - -/** - * Notifies the user of sign in successes or failures beyond the lifecycle of an activity. - */ -public class SignInResultNotifier implements OnCompleteListener { - private Context mContext; - - public SignInResultNotifier(@NonNull Context context) { - mContext = context.getApplicationContext(); - } - - @Override - public void onComplete(@NonNull Task task) { - if (task.isSuccessful()) { - Toast.makeText(mContext, R.string.signed_in, Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(mContext, R.string.anonymous_auth_failed_msg, Toast.LENGTH_LONG).show(); - } - } -} diff --git a/composeapp/src/main/res/drawable-hdpi/firebase_auth.png b/app/src/main/res/drawable-hdpi/firebase_auth.png similarity index 100% rename from composeapp/src/main/res/drawable-hdpi/firebase_auth.png rename to app/src/main/res/drawable-hdpi/firebase_auth.png diff --git a/app/src/main/res/drawable-hdpi/firebase_auth_120dp.png b/app/src/main/res/drawable-hdpi/firebase_auth_120dp.png deleted file mode 100644 index b03b18b5328a0c33551c66183a648dac54836187..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14632 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 diff --git a/composeapp/src/main/res/drawable-mdpi/firebase_auth.png b/app/src/main/res/drawable-mdpi/firebase_auth.png similarity index 100% rename from composeapp/src/main/res/drawable-mdpi/firebase_auth.png rename to app/src/main/res/drawable-mdpi/firebase_auth.png diff --git a/app/src/main/res/drawable-mdpi/firebase_auth_120dp.png b/app/src/main/res/drawable-mdpi/firebase_auth_120dp.png deleted file mode 100644 index 820ba76f9072f6b9bac53c8eeec9fa1a97e7fdd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7189 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 diff --git a/composeapp/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml similarity index 100% rename from composeapp/src/main/res/drawable-v24/ic_launcher_foreground.xml rename to app/src/main/res/drawable-v24/ic_launcher_foreground.xml diff --git a/composeapp/src/main/res/drawable-xhdpi/firebase_auth.png b/app/src/main/res/drawable-xhdpi/firebase_auth.png similarity index 100% rename from composeapp/src/main/res/drawable-xhdpi/firebase_auth.png rename to app/src/main/res/drawable-xhdpi/firebase_auth.png diff --git a/app/src/main/res/drawable-xhdpi/firebase_auth_120dp.png b/app/src/main/res/drawable-xhdpi/firebase_auth_120dp.png deleted file mode 100644 index 351fa59fe5a0c215853266f7ae53ed06e2d2b001..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15823 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 diff --git a/composeapp/src/main/res/drawable-xxxhdpi/firebase_auth.png b/app/src/main/res/drawable-xxxhdpi/firebase_auth.png similarity index 100% rename from composeapp/src/main/res/drawable-xxxhdpi/firebase_auth.png rename to app/src/main/res/drawable-xxxhdpi/firebase_auth.png diff --git a/app/src/main/res/drawable-xxxhdpi/firebase_auth_120dp.png b/app/src/main/res/drawable-xxxhdpi/firebase_auth_120dp.png deleted file mode 100644 index 9b68e8ade0dbed106857e558c5472bf511e6dd03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35146 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 - - - diff --git a/app/src/main/res/drawable/ic_anon_user_48dp.xml b/app/src/main/res/drawable/ic_anon_user_48dp.xml deleted file mode 100644 index 0fb12013f..000000000 --- a/app/src/main/res/drawable/ic_anon_user_48dp.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_chat_message_arrow.xml b/app/src/main/res/drawable/ic_chat_message_arrow.xml deleted file mode 100644 index 5063dc73e..000000000 --- a/app/src/main/res/drawable/ic_chat_message_arrow.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/ic_chat_message_background.xml b/app/src/main/res/drawable/ic_chat_message_background.xml deleted file mode 100644 index c22c3d71a..000000000 --- a/app/src/main/res/drawable/ic_chat_message_background.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/composeapp/src/main/res/drawable/ic_discord_24dp.xml b/app/src/main/res/drawable/ic_discord_24dp.xml similarity index 100% rename from composeapp/src/main/res/drawable/ic_discord_24dp.xml rename to app/src/main/res/drawable/ic_discord_24dp.xml diff --git a/app/src/main/res/drawable/ic_googleg_color_144dp.xml b/app/src/main/res/drawable/ic_googleg_color_144dp.xml deleted file mode 100644 index 820e04185..000000000 --- a/app/src/main/res/drawable/ic_googleg_color_144dp.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - diff --git a/composeapp/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from composeapp/src/main/res/drawable/ic_launcher_background.xml rename to app/src/main/res/drawable/ic_launcher_background.xml diff --git a/composeapp/src/main/res/drawable/ic_line_logo_24dp.xml b/app/src/main/res/drawable/ic_line_logo_24dp.xml similarity index 100% rename from composeapp/src/main/res/drawable/ic_line_logo_24dp.xml rename to app/src/main/res/drawable/ic_line_logo_24dp.xml diff --git a/app/src/main/res/layout-land/auth_method_picker_custom_layout.xml b/app/src/main/res/layout-land/auth_method_picker_custom_layout.xml deleted file mode 100644 index 52a234d53..000000000 --- a/app/src/main/res/layout-land/auth_method_picker_custom_layout.xml +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_anonymous_upgrade.xml b/app/src/main/res/layout/activity_anonymous_upgrade.xml deleted file mode 100644 index 2677a1c71..000000000 --- a/app/src/main/res/layout/activity_anonymous_upgrade.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - -