From 3b736ad32a7fad50ae63ee40f9919e4b0a314e4a Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Fri, 10 Mar 2023 11:15:32 -0500 Subject: [PATCH 01/14] initial Auth deprecations --- .../integration_test/src/integration_test.cc | 18 +- auth/integration_test/src/integration_test.cc | 274 +++++++++--------- auth/samples/src/doc_samples.cc | 66 ++--- auth/src/android/auth_android.cc | 18 +- auth/src/android/common_android.cc | 4 +- auth/src/auth.cc | 14 +- auth/src/data.h | 26 +- auth/src/desktop/auth_desktop.cc | 26 +- auth/src/desktop/authentication_result.cc | 2 +- auth/src/desktop/user_desktop.cc | 4 +- auth/src/include/firebase/auth.h | 73 +++-- auth/src/ios/auth_ios.mm | 16 +- .../google/firebase/auth/FirebaseAuth.java | 6 +- auth/tests/auth_test.cc | 34 +-- auth/tests/desktop/auth_desktop_test.cc | 42 +-- auth/tests/desktop/user_desktop_test.cc | 10 +- auth/tests/user_test.cc | 6 +- .../integration_test/src/integration_test.cc | 16 +- .../integration_test/src/integration_test.cc | 16 +- .../src/firestore_test.cc | 2 +- .../src/integration_test.cc | 16 +- .../integration_test/src/integration_test.cc | 4 +- .../integration_test/src/integration_test.cc | 16 +- 23 files changed, 368 insertions(+), 341 deletions(-) diff --git a/app_check/integration_test/src/integration_test.cc b/app_check/integration_test/src/integration_test.cc index 4220b79967..9f20d02ac4 100644 --- a/app_check/integration_test/src/integration_test.cc +++ b/app_check/integration_test/src/integration_test.cc @@ -391,13 +391,13 @@ void FirebaseAppCheckTest::TerminateFunctions() { } void FirebaseAppCheckTest::SignIn() { - if (auth_->current_user() != nullptr) { + if (auth_->current_user_DEPRECATED() != nullptr) { // Already signed in. return; } LogDebug("Signing in."); firebase::Future sign_in_future = - auth_->SignInAnonymously(); + auth_->SignInAnonymously_DEPRECATED(); WaitForCompletion(sign_in_future, "SignInAnonymously"); if (sign_in_future.error() != 0) { FAIL() << "Ensure your application has the Anonymous sign-in provider " @@ -411,15 +411,15 @@ void FirebaseAppCheckTest::SignOut() { // Auth is not set up. return; } - if (auth_->current_user() == nullptr) { + if (auth_->current_user_DEPRECATED() == nullptr) { // Already signed out. return; } - if (auth_->current_user()->is_anonymous()) { + if (auth_->current_user_DEPRECATED()->is_anonymous()) { // If signed in anonymously, delete the anonymous user. - WaitForCompletion(auth_->current_user()->Delete(), "DeleteAnonymousUser"); + WaitForCompletion(auth_->current_user_DEPRECATED()->Delete(), "DeleteAnonymousUser"); // If there was a problem deleting the user, try to sign out at least. - if (auth_->current_user()) { + if (auth_->current_user_DEPRECATED()) { auth_->SignOut(); } } else { @@ -428,11 +428,11 @@ void FirebaseAppCheckTest::SignOut() { auth_->SignOut(); // Wait for the sign-out to finish. - while (auth_->current_user() != nullptr) { + while (auth_->current_user_DEPRECATED() != nullptr) { if (ProcessEvents(100)) break; } } - EXPECT_EQ(auth_->current_user(), nullptr); + EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); } firebase::database::DatabaseReference FirebaseAppCheckTest::CreateWorkingPath( @@ -544,7 +544,7 @@ TEST_F(FirebaseAppCheckTest, TestSignIn) { InitializeAppCheckWithDebug(); InitializeApp(); InitializeAuth(); - EXPECT_NE(auth_->current_user(), nullptr); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); } TEST_F(FirebaseAppCheckTest, TestDebugProviderValidToken) { diff --git a/auth/integration_test/src/integration_test.cc b/auth/integration_test/src/integration_test.cc index 940382a68b..f7faa0b5da 100644 --- a/auth/integration_test/src/integration_test.cc +++ b/auth/integration_test/src/integration_test.cc @@ -206,7 +206,7 @@ bool FirebaseAuthTest::WaitForCompletion( if (expected_error == ::firebase::auth::kAuthErrorNone) { const firebase::auth::User* future_result_user = future.result() ? *future.result() : nullptr; - const firebase::auth::User* auth_user = auth_->current_user(); + const firebase::auth::User* auth_user = auth_->current_user_DEPRECATED(); EXPECT_EQ(future_result_user, auth_user) << "User returned by Future doesn't match User in Auth"; return (future_result_user == auth_user); @@ -225,7 +225,7 @@ bool FirebaseAuthTest::WaitForCompletion( const firebase::auth::User* future_result_user = (future.result() && future.result()->user) ? future.result()->user : nullptr; - const firebase::auth::User* auth_user = auth_->current_user(); + const firebase::auth::User* auth_user = auth_->current_user_DEPRECATED(); EXPECT_EQ(future_result_user, auth_user) << "User returned by Future doesn't match User in Auth"; return (future_result_user == auth_user); @@ -251,22 +251,22 @@ void FirebaseAuthTest::SignOut() { // Auth is not set up. return; } - if (auth_->current_user() == nullptr) { + if (auth_->current_user_DEPRECATED() == nullptr) { // Already signed out. return; } auth_->SignOut(); // Wait for the sign-out to finish. - while (auth_->current_user() != nullptr) { + while (auth_->current_user_DEPRECATED() != nullptr) { if (ProcessEvents(100)) break; } ProcessEvents(100); - EXPECT_EQ(auth_->current_user(), nullptr); + EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); } void FirebaseAuthTest::DeleteUser() { - if (auth_ != nullptr && auth_->current_user() != nullptr) { - FirebaseTest::WaitForCompletion(auth_->current_user()->Delete(), + if (auth_ != nullptr && auth_->current_user_DEPRECATED() != nullptr) { + FirebaseTest::WaitForCompletion(auth_->current_user_DEPRECATED()->Delete(), "Delete User"); ProcessEvents(100); } @@ -280,9 +280,9 @@ TEST_F(FirebaseAuthTest, TestInitialization) { TEST_F(FirebaseAuthTest, TestAnonymousSignin) { // Test notification on SignIn(). - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); - EXPECT_NE(auth_->current_user(), nullptr); - EXPECT_TRUE(auth_->current_user()->is_anonymous()); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); + EXPECT_TRUE(auth_->current_user_DEPRECATED()->is_anonymous()); DeleteUser(); } @@ -313,7 +313,7 @@ class TestAuthStateListener : public firebase::auth::AuthStateListener { virtual void OnAuthStateChanged(firebase::auth::Auth* auth) { // NOLINT // Log the provider ID. std::string provider = - auth->current_user() ? auth->current_user()->provider_id() : ""; + auth->current_user_DEPRECATED() ? auth->current_user_DEPRECATED()->provider_id() : ""; LogDebug("OnAuthStateChanged called, provider=%s", provider.c_str()); if (auth_states_.empty() || auth_states_.back() != provider) { // Only log unique events. @@ -331,9 +331,9 @@ class TestIdTokenListener : public firebase::auth::IdTokenListener { virtual void OnIdTokenChanged(firebase::auth::Auth* auth) { // NOLINT // Log the auth token (if available). std::string token = ""; - if (auth->current_user()) { + if (auth->current_user_DEPRECATED()) { firebase::Future token_future = - auth->current_user()->GetToken(false); + auth->current_user_DEPRECATED()->GetToken(false); if (token_future.status() == firebase::kFutureStatusComplete) { if (token_future.error() == 0) { token = *token_future.result(); @@ -366,15 +366,15 @@ TEST_F(FirebaseAuthTest, TestTokensAndAuthStateListeners) { TestIdTokenListener token_listener; auth_->AddAuthStateListener(&listener); auth_->AddIdTokenListener(&token_listener); - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); // Get an initial token. firebase::Future token_future = - auth_->current_user()->GetToken(false); + auth_->current_user_DEPRECATED()->GetToken(false); WaitForCompletion(token_future, "GetToken(false)"); std::string first_token = *token_future.result(); // Force a token refresh. ProcessEvents(1000); - token_future = auth_->current_user()->GetToken(true); + token_future = auth_->current_user_DEPRECATED()->GetToken(true); WaitForCompletion(token_future, "GetToken(true)"); EXPECT_NE(*token_future.result(), ""); std::string second_token = *token_future.result(); @@ -409,55 +409,55 @@ TEST_F(FirebaseAuthTest, TestEmailAndPasswordSignin) { // Register a random email and password. This signs us in as that user. std::string password = kTestPassword; firebase::Future create_user = - auth_->CreateUserWithEmailAndPassword(email.c_str(), password.c_str()); - WaitForCompletion(create_user, "CreateUserWithEmailAndPassword"); - EXPECT_NE(auth_->current_user(), nullptr); - // Sign out and log in using SignInWithCredential(EmailCredential). + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), password.c_str()); + WaitForCompletion(create_user, "CreateUserWithEmailAndPassword_DEPRECATED"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); + // Sign out and log in using SignInWithCredential_DEPRECATED(EmailCredential). SignOut(); { firebase::auth::Credential email_credential = firebase::auth::EmailAuthProvider::GetCredential(email.c_str(), password.c_str()); - WaitForCompletion(auth_->SignInWithCredential(email_credential), + WaitForCompletion(auth_->SignInWithCredential_DEPRECATED(email_credential), "SignInWithCredential"); - EXPECT_NE(auth_->current_user(), nullptr); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); } // Sign out and log in using - // SignInAndRetrieveDataWithCredential(EmailCredential). + // SignInAndRetrieveDataWithCredential_DEPRECATED(EmailCredential). SignOut(); { firebase::auth::Credential email_credential = firebase::auth::EmailAuthProvider::GetCredential(email.c_str(), password.c_str()); WaitForCompletion( - auth_->SignInAndRetrieveDataWithCredential(email_credential), + auth_->SignInAndRetrieveDataWithCredential_DEPRECATED(email_credential), "SignAndRetrieveDataInWithCredential"); - EXPECT_NE(auth_->current_user(), nullptr); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); } SignOut(); // Sign in with SignInWithEmailAndPassword values. firebase::Future sign_in_user = - auth_->SignInWithEmailAndPassword(email.c_str(), password.c_str()); + auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), password.c_str()); WaitForCompletion(sign_in_user, "SignInWithEmailAndPassword"); - ASSERT_NE(auth_->current_user(), nullptr); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); // Then delete the account. - firebase::Future delete_user = auth_->current_user()->Delete(); + firebase::Future delete_user = auth_->current_user_DEPRECATED()->Delete(); WaitForCompletion(delete_user, "Delete"); firebase::Future invalid_sign_in_user = - auth_->SignInWithEmailAndPassword(email.c_str(), password.c_str()); + auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), password.c_str()); WaitForCompletion(invalid_sign_in_user, "SignInWithEmailAndPassword (invalid user)", firebase::auth::kAuthErrorUserNotFound); - EXPECT_EQ(auth_->current_user(), nullptr); + EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); } TEST_F(FirebaseAuthTest, TestUpdateUserProfile) { std::string email = GenerateEmailAddress(); firebase::Future create_user = - auth_->CreateUserWithEmailAndPassword(email.c_str(), kTestPassword); - WaitForCompletion(create_user, "CreateUserWithEmailAndPassword"); - EXPECT_NE(auth_->current_user(), nullptr); + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword); + WaitForCompletion(create_user, "CreateUserWithEmailAndPassword_DEPRECATED"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); // Set some user profile properties. firebase::auth::User* user = *create_user.result(); const char kDisplayName[] = "Hello World"; @@ -471,7 +471,7 @@ TEST_F(FirebaseAuthTest, TestUpdateUserProfile) { EXPECT_EQ(user->photo_url(), kPhotoUrl); SignOut(); WaitForCompletion( - auth_->SignInWithEmailAndPassword(email.c_str(), kTestPassword), + auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), "SignInWithEmailAndPassword"); EXPECT_EQ(user->display_name(), kDisplayName); EXPECT_EQ(user->photo_url(), kPhotoUrl); @@ -481,10 +481,10 @@ TEST_F(FirebaseAuthTest, TestUpdateUserProfile) { TEST_F(FirebaseAuthTest, TestUpdateEmailAndPassword) { std::string email = GenerateEmailAddress(); WaitForCompletion( - auth_->CreateUserWithEmailAndPassword(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword"); - ASSERT_NE(auth_->current_user(), nullptr); - firebase::auth::User* user = auth_->current_user(); + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED"); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); + firebase::auth::User* user = auth_->current_user_DEPRECATED(); // Update the user's email and password. const std::string new_email = "new_" + email; @@ -496,16 +496,16 @@ TEST_F(FirebaseAuthTest, TestUpdateEmailAndPassword) { firebase::auth::EmailAuthProvider::GetCredential(new_email.c_str(), kTestPasswordUpdated); WaitForCompletion(user->Reauthenticate(new_email_cred), "Reauthenticate"); - EXPECT_NE(auth_->current_user(), nullptr); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); WaitForCompletion(user->SendEmailVerification(), "SendEmailVerification"); DeleteUser(); } TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithEmailCredential) { - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); - ASSERT_NE(auth_->current_user(), nullptr); - firebase::auth::User* user = auth_->current_user(); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); + firebase::auth::User* user = auth_->current_user_DEPRECATED(); std::string email = GenerateEmailAddress(); firebase::auth::Credential credential = firebase::auth::EmailAuthProvider::GetCredential(email.c_str(), @@ -514,8 +514,8 @@ TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithEmailCredential) { "LinkAndRetrieveDataWithCredential"); WaitForCompletion(user->Unlink(credential.provider().c_str()), "Unlink"); SignOut(); - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); - EXPECT_NE(auth_->current_user(), nullptr); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); std::string email1 = GenerateEmailAddress(); firebase::auth::Credential credential1 = firebase::auth::EmailAuthProvider::GetCredential(email1.c_str(), @@ -534,9 +534,9 @@ TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithEmailCredential) { } TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithBadCredential) { - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); - ASSERT_NE(auth_->current_user(), nullptr); - firebase::auth::User* pre_link_user = auth_->current_user(); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); + firebase::auth::User* pre_link_user = auth_->current_user_DEPRECATED(); firebase::auth::Credential twitter_cred = firebase::auth::TwitterAuthProvider::GetCredential(kTestIdTokenBad, kTestAccessTokenBad); @@ -544,116 +544,116 @@ TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithBadCredential) { "LinkWithCredential", firebase::auth::kAuthErrorInvalidCredential); // Ensure that user stays the same. - EXPECT_EQ(auth_->current_user(), pre_link_user); + EXPECT_EQ(auth_->current_user_DEPRECATED(), pre_link_user); DeleteUser(); } TEST_F(FirebaseAuthTest, TestSignInWithBadEmailFails) { WaitForCompletion( - auth_->SignInWithEmailAndPassword(kTestEmailBad, kTestPassword), + auth_->SignInWithEmailAndPassword_DEPRECATED(kTestEmailBad, kTestPassword), "SignInWithEmailAndPassword", firebase::auth::kAuthErrorUserNotFound); - EXPECT_EQ(auth_->current_user(), nullptr); + EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); } TEST_F(FirebaseAuthTest, TestSignInWithBadPasswordFails) { std::string email = GenerateEmailAddress(); WaitForCompletion( - auth_->CreateUserWithEmailAndPassword(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword"); - EXPECT_NE(auth_->current_user(), nullptr); + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); SignOut(); WaitForCompletion( - auth_->SignInWithEmailAndPassword(email.c_str(), kTestPasswordBad), + auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPasswordBad), "SignInWithEmailAndPassword", firebase::auth::kAuthErrorWrongPassword); - EXPECT_EQ(auth_->current_user(), nullptr); + EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); SignOut(); // Sign back in and delete the user. WaitForCompletion( - auth_->SignInWithEmailAndPassword(email.c_str(), kTestPassword), + auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), "SignInWithEmailAndPassword"); - EXPECT_NE(auth_->current_user(), nullptr); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); DeleteUser(); } TEST_F(FirebaseAuthTest, TestCreateUserWithExistingEmailFails) { std::string email = GenerateEmailAddress(); WaitForCompletion( - auth_->CreateUserWithEmailAndPassword(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword 1"); - EXPECT_NE(auth_->current_user(), nullptr); + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED 1"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); SignOut(); WaitForCompletion( - auth_->CreateUserWithEmailAndPassword(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword 2", + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED 2", firebase::auth::kAuthErrorEmailAlreadyInUse); - EXPECT_EQ(auth_->current_user(), nullptr); + EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); SignOut(); // Try again with a different password. WaitForCompletion( - auth_->CreateUserWithEmailAndPassword(email.c_str(), kTestPasswordBad), - "CreateUserWithEmailAndPassword 3", + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPasswordBad), + "CreateUserWithEmailAndPassword_DEPRECATED 3", firebase::auth::kAuthErrorEmailAlreadyInUse); - EXPECT_EQ(auth_->current_user(), nullptr); + EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); SignOut(); WaitForCompletion( - auth_->SignInWithEmailAndPassword(email.c_str(), kTestPassword), + auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), "SignInWithEmailAndPassword"); - EXPECT_NE(auth_->current_user(), nullptr); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); DeleteUser(); } TEST_F(FirebaseAuthTest, TestSignInWithBadCredentials) { // Get an anonymous user first. - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); - ASSERT_NE(auth_->current_user(), nullptr); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); // Hold on to the existing user, to make sure it is unchanged by bad signins. - firebase::auth::User* existing_user = auth_->current_user(); + firebase::auth::User* existing_user = auth_->current_user_DEPRECATED(); // Test signing in with a variety of bad credentials. - WaitForCompletion(auth_->SignInWithCredential( + WaitForCompletion(auth_->SignInWithCredential_DEPRECATED( firebase::auth::FacebookAuthProvider::GetCredential( kTestAccessTokenBad)), "SignInWithCredential (Facebook)", firebase::auth::kAuthErrorInvalidCredential); // Ensure that failing to sign in with a credential doesn't modify the user. - EXPECT_EQ(auth_->current_user(), existing_user); - WaitForCompletion(auth_->SignInWithCredential( + EXPECT_EQ(auth_->current_user_DEPRECATED(), existing_user); + WaitForCompletion(auth_->SignInWithCredential_DEPRECATED( firebase::auth::TwitterAuthProvider::GetCredential( kTestIdTokenBad, kTestAccessTokenBad)), "SignInWithCredential (Twitter)", firebase::auth::kAuthErrorInvalidCredential); - EXPECT_EQ(auth_->current_user(), existing_user); - WaitForCompletion(auth_->SignInWithCredential( + EXPECT_EQ(auth_->current_user_DEPRECATED(), existing_user); + WaitForCompletion(auth_->SignInWithCredential_DEPRECATED( firebase::auth::GitHubAuthProvider::GetCredential( kTestAccessTokenBad)), "SignInWithCredential (GitHub)", firebase::auth::kAuthErrorInvalidCredential); - EXPECT_EQ(auth_->current_user(), existing_user); - WaitForCompletion(auth_->SignInWithCredential( + EXPECT_EQ(auth_->current_user_DEPRECATED(), existing_user); + WaitForCompletion(auth_->SignInWithCredential_DEPRECATED( firebase::auth::GoogleAuthProvider::GetCredential( kTestIdTokenBad, kTestAccessTokenBad)), "SignInWithCredential (Google 1)", firebase::auth::kAuthErrorInvalidCredential); - EXPECT_EQ(auth_->current_user(), existing_user); - WaitForCompletion(auth_->SignInWithCredential( + EXPECT_EQ(auth_->current_user_DEPRECATED(), existing_user); + WaitForCompletion(auth_->SignInWithCredential_DEPRECATED( firebase::auth::GoogleAuthProvider::GetCredential( kTestIdTokenBad, nullptr)), "SignInWithCredential (Google 2)", firebase::auth::kAuthErrorInvalidCredential); - EXPECT_EQ(auth_->current_user(), existing_user); + EXPECT_EQ(auth_->current_user_DEPRECATED(), existing_user); WaitForCompletion( - auth_->SignInWithCredential(firebase::auth::OAuthProvider::GetCredential( + auth_->SignInWithCredential_DEPRECATED(firebase::auth::OAuthProvider::GetCredential( kTestIdProviderIdBad, kTestIdTokenBad, kTestAccessTokenBad)), "SignInWithCredential (OAuth)", firebase::auth::kAuthErrorFailure); - EXPECT_EQ(auth_->current_user(), existing_user); + EXPECT_EQ(auth_->current_user_DEPRECATED(), existing_user); #if defined(__ANDROID__) // Test Play Games sign-in on Android only. - WaitForCompletion(auth_->SignInWithCredential( + WaitForCompletion(auth_->SignInWithCredential_DEPRECATED( firebase::auth::PlayGamesAuthProvider::GetCredential( kTestServerAuthCodeBad)), "SignInWithCredential (Play Games)", firebase::auth::kAuthErrorInvalidCredential); - EXPECT_EQ(auth_->current_user(), existing_user); + EXPECT_EQ(auth_->current_user_DEPRECATED(), existing_user); #endif // defined(__ANDROID__) DeleteUser(); } @@ -674,7 +674,7 @@ TEST_F(FirebaseAuthTest, TestGameCenterSignIn) { EXPECT_NE(credential_future.result(), nullptr); if (credential_future.result()) { - WaitForCompletion(auth_->SignInWithCredential(*credential_future.result()), + WaitForCompletion(auth_->SignInWithCredential_DEPRECATED(*credential_future.result()), "SignInWithCredential (Game Center)"); } DeleteUser(); @@ -685,9 +685,9 @@ TEST_F(FirebaseAuthTest, TestSendPasswordResetEmail) { // Test Auth::SendPasswordResetEmail(). std::string email = GenerateEmailAddress(); WaitForCompletion( - auth_->CreateUserWithEmailAndPassword(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword"); - EXPECT_NE(auth_->current_user(), nullptr); + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); SignOut(); // Send to correct email. WaitForCompletion(auth_->SendPasswordResetEmail(email.c_str()), @@ -698,9 +698,9 @@ TEST_F(FirebaseAuthTest, TestSendPasswordResetEmail) { firebase::auth::kAuthErrorUserNotFound); // Delete user now that we are done with it. WaitForCompletion( - auth_->SignInWithEmailAndPassword(email.c_str(), kTestPassword), + auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), "SignInWithEmailAndPassword"); - EXPECT_NE(auth_->current_user(), nullptr); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); DeleteUser(); } @@ -714,9 +714,9 @@ TEST_F(FirebaseAuthTest, TestWithCustomEmailAndPassword) { return; } firebase::Future sign_in_user = - auth_->SignInWithEmailAndPassword(kCustomTestEmail, kCustomTestPassword); + auth_->SignInWithEmailAndPassword_DEPRECATED(kCustomTestEmail, kCustomTestPassword); WaitForCompletion(sign_in_user, "SignInWithEmailAndPassword"); - EXPECT_NE(auth_->current_user(), nullptr); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); } TEST_F(FirebaseAuthTest, TestAuthPersistenceWithAnonymousSignin) { @@ -725,15 +725,15 @@ TEST_F(FirebaseAuthTest, TestAuthPersistenceWithAnonymousSignin) { FLAKY_TEST_SECTION_BEGIN(); - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); - EXPECT_NE(auth_->current_user(), nullptr); - EXPECT_TRUE(auth_->current_user()->is_anonymous()); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); + EXPECT_TRUE(auth_->current_user_DEPRECATED()->is_anonymous()); Terminate(); ProcessEvents(2000); Initialize(); EXPECT_NE(auth_, nullptr); - EXPECT_NE(auth_->current_user(), nullptr); - EXPECT_TRUE(auth_->current_user()->is_anonymous()); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); + EXPECT_TRUE(auth_->current_user_DEPRECATED()->is_anonymous()); DeleteUser(); FLAKY_TEST_SECTION_END(); @@ -746,38 +746,38 @@ TEST_F(FirebaseAuthTest, TestAuthPersistenceWithEmailSignin) { std::string email = GenerateEmailAddress(); WaitForCompletion( - auth_->CreateUserWithEmailAndPassword(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword"); - EXPECT_NE(auth_->current_user(), nullptr); - EXPECT_FALSE(auth_->current_user()->is_anonymous()); - std::string prev_provider_id = auth_->current_user()->provider_id(); + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); + EXPECT_FALSE(auth_->current_user_DEPRECATED()->is_anonymous()); + std::string prev_provider_id = auth_->current_user_DEPRECATED()->provider_id(); // Save the old provider ID list so we can make sure it's the same once // it's loaded again. std::vector prev_provider_data_ids; - for (int i = 0; i < auth_->current_user()->provider_data().size(); i++) { + for (int i = 0; i < auth_->current_user_DEPRECATED()->provider_data().size(); i++) { prev_provider_data_ids.push_back( - auth_->current_user()->provider_data()[i]->provider_id()); + auth_->current_user_DEPRECATED()->provider_data()[i]->provider_id()); } Terminate(); ProcessEvents(2000); Initialize(); EXPECT_NE(auth_, nullptr); - EXPECT_NE(auth_->current_user(), nullptr); - EXPECT_FALSE(auth_->current_user()->is_anonymous()); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); + EXPECT_FALSE(auth_->current_user_DEPRECATED()->is_anonymous()); // Make sure the provider IDs are the same as they were before. - EXPECT_EQ(auth_->current_user()->provider_id(), prev_provider_id); + EXPECT_EQ(auth_->current_user_DEPRECATED()->provider_id(), prev_provider_id); std::vector loaded_provider_data_ids; - for (int i = 0; i < auth_->current_user()->provider_data().size(); i++) { + for (int i = 0; i < auth_->current_user_DEPRECATED()->provider_data().size(); i++) { loaded_provider_data_ids.push_back( - auth_->current_user()->provider_data()[i]->provider_id()); + auth_->current_user_DEPRECATED()->provider_data()[i]->provider_id()); } EXPECT_TRUE(loaded_provider_data_ids == prev_provider_data_ids); // Cleanup, ensure we are signed in as the user so we can delete it. WaitForCompletion( - auth_->SignInWithEmailAndPassword(email.c_str(), kTestPassword), + auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), "SignInWithEmailAndPassword"); - EXPECT_NE(auth_->current_user(), nullptr); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); DeleteUser(); FLAKY_TEST_SECTION_END(); @@ -904,8 +904,8 @@ TEST_F(FirebaseAuthTest, TestPhoneAuth) { } if (listener.on_verification_complete_count() > 0) { LogDebug("Signing in with automatic verification code."); - WaitForCompletion(auth_->SignInWithCredential(listener.credential()), - "SignInWithCredential(PhoneCredential) automatic"); + WaitForCompletion(auth_->SignInWithCredential_DEPRECATED(listener.credential()), + "SignInWithCredential_DEPRECATED(PhoneCredential) automatic"); } else if (listener.on_verification_failed_count() > 0) { FAIL() << "Automatic verification failed."; } else { @@ -917,8 +917,8 @@ TEST_F(FirebaseAuthTest, TestPhoneAuth) { phone_provider.GetCredential(listener.verification_id().c_str(), kPhoneAuthTestVerificationCode); - WaitForCompletion(auth_->SignInWithCredential(phone_credential), - "SignInWithCredential(PhoneCredential)"); + WaitForCompletion(auth_->SignInWithCredential_DEPRECATED(phone_credential), + "SignInWithCredential_DEPRECATED(PhoneCredential)"); } ProcessEvents(1000); @@ -939,7 +939,7 @@ TEST_F(FirebaseAuthTest, TestSuccessfulSignInFederatedProviderNoScopes) { provider_id, /*scopes=*/{}, /*custom_parameters=*/{{"req_id", "1234"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->SignInWithProvider(&provider); + auth_->SignInWithProvider_DEPRECATED(&provider); WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id); DeleteUser(); } @@ -955,7 +955,7 @@ TEST_F(FirebaseAuthTest, provider_id, /*scopes=*/{}, /*custom_parameters=*/{}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->SignInWithProvider(&provider); + auth_->SignInWithProvider_DEPRECATED(&provider); WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id); DeleteUser(); } @@ -972,7 +972,7 @@ TEST_F(FirebaseAuthTest, TestSuccessfulSignInFederatedProvider) { /*custom_parameters=*/{{"req_id", "1234"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->SignInWithProvider(&provider); + auth_->SignInWithProvider_DEPRECATED(&provider); WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id); DeleteUser(); } @@ -987,7 +987,7 @@ TEST_F(FirebaseAuthTest, TestSignInFederatedProviderBadProviderIdFails) { /*custom_parameters=*/{{"req_id", "5321"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->SignInWithProvider(&provider); + auth_->SignInWithProvider_DEPRECATED(&provider); WaitForCompletion(sign_in_future, "SignInWithProvider", firebase::auth::kAuthErrorInvalidProviderId); } @@ -1005,7 +1005,7 @@ TEST_F(FirebaseAuthTest, TestSuccessfulReauthenticateWithProvider) { /*custom_parameters=*/{{"req_id", "1234"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->SignInWithProvider(&provider); + auth_->SignInWithProvider_DEPRECATED(&provider); if (WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id)) { WaitForCompletion( sign_in_future.result()->user->ReauthenticateWithProvider(&provider), @@ -1024,7 +1024,7 @@ TEST_F(FirebaseAuthTest, TestSuccessfulReauthenticateWithProviderNoScopes) { provider_id, /*scopes=*/{}, /*custom_parameters=*/{{"req_id", "1234"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->SignInWithProvider(&provider); + auth_->SignInWithProvider_DEPRECATED(&provider); if (WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id)) { WaitForCompletion( sign_in_future.result()->user->ReauthenticateWithProvider(&provider), @@ -1044,7 +1044,7 @@ TEST_F(FirebaseAuthTest, provider_id, /*scopes=*/{}, /*custom_parameters=*/{}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->SignInWithProvider(&provider); + auth_->SignInWithProvider_DEPRECATED(&provider); if (WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id)) { WaitForCompletion( sign_in_future.result()->user->ReauthenticateWithProvider(&provider), @@ -1062,12 +1062,12 @@ TEST_F(FirebaseAuthTest, TestReauthenticateWithProviderBadProviderIdFails) { firebase::auth::FederatedOAuthProviderData provider_data(provider_id); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->SignInWithProvider(&provider); + auth_->SignInWithProvider_DEPRECATED(&provider); if (WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id)) { provider_data.provider_id = "MadeUpProvider"; firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future reauth_future = - auth_->current_user()->ReauthenticateWithProvider(&provider); + auth_->current_user_DEPRECATED()->ReauthenticateWithProvider(&provider); WaitForCompletion(reauth_future, "ReauthenticateWithProvider", firebase::auth::kAuthErrorInvalidProviderId); } @@ -1078,15 +1078,15 @@ TEST_F(FirebaseAuthTest, TestReauthenticateWithProviderBadProviderIdFails) { TEST_F(FirebaseAuthTest, TestSuccessfulLinkFederatedProviderNoScopes) { SKIP_TEST_ON_DESKTOP; TEST_REQUIRES_USER_INTERACTION; - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); - ASSERT_NE(auth_->current_user(), nullptr); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); const std::string provider_id = firebase::auth::GoogleAuthProvider::kProviderId; firebase::auth::FederatedOAuthProviderData provider_data( provider_id, /*scopes=*/{}, /*custom_parameters=*/{{"req_id", "1234"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->current_user()->LinkWithProvider(&provider); + auth_->current_user_DEPRECATED()->LinkWithProvider(&provider); WaitForCompletion(sign_in_future, "LinkWithProvider", provider_id); DeleteUser(); } @@ -1096,15 +1096,15 @@ TEST_F(FirebaseAuthTest, SKIP_TEST_ON_DESKTOP; TEST_REQUIRES_USER_INTERACTION; - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); - ASSERT_NE(auth_->current_user(), nullptr); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); const std::string provider_id = firebase::auth::GoogleAuthProvider::kProviderId; firebase::auth::FederatedOAuthProviderData provider_data( provider_id, /*scopes=*/{}, /*custom_parameters=*/{}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->current_user()->LinkWithProvider(&provider); + auth_->current_user_DEPRECATED()->LinkWithProvider(&provider); WaitForCompletion(sign_in_future, "LinkWithProvider", provider_id); DeleteUser(); } @@ -1113,8 +1113,8 @@ TEST_F(FirebaseAuthTest, TestSuccessfulLinkFederatedProvider) { SKIP_TEST_ON_DESKTOP; TEST_REQUIRES_USER_INTERACTION; - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); - ASSERT_NE(auth_->current_user(), nullptr); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); const std::string provider_id = firebase::auth::GoogleAuthProvider::kProviderId; firebase::auth::FederatedOAuthProviderData provider_data( @@ -1123,7 +1123,7 @@ TEST_F(FirebaseAuthTest, TestSuccessfulLinkFederatedProvider) { /*custom_parameters=*/{{"req_id", "1234"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->current_user()->LinkWithProvider(&provider); + auth_->current_user_DEPRECATED()->LinkWithProvider(&provider); WaitForCompletion(sign_in_future, "LinkWithProvider", provider_id); DeleteUser(); } @@ -1132,15 +1132,15 @@ TEST_F(FirebaseAuthTest, TestLinkFederatedProviderBadProviderIdFails) { SKIP_TEST_ON_DESKTOP; TEST_REQUIRES_USER_INTERACTION; - WaitForCompletion(auth_->SignInAnonymously(), "SignInAnonymously"); - ASSERT_NE(auth_->current_user(), nullptr); + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); firebase::auth::FederatedOAuthProviderData provider_data( /*provider=*/"MadeUpProvider", /*scopes=*/{"https://www.googleapis.com/auth/fitness.activity.read"}, /*custom_parameters=*/{{"req_id", "1234"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->current_user()->LinkWithProvider(&provider); + auth_->current_user_DEPRECATED()->LinkWithProvider(&provider); WaitForCompletion(sign_in_future, "LinkWithProvider", firebase::auth::kAuthErrorInvalidProviderId); DeleteUser(); diff --git a/auth/samples/src/doc_samples.cc b/auth/samples/src/doc_samples.cc index bcde0eaae8..f9eae3045a 100644 --- a/auth/samples/src/doc_samples.cc +++ b/auth/samples/src/doc_samples.cc @@ -119,7 +119,7 @@ void VariousSignIns(firebase::auth::Auth* auth) { { // [START auth_create_user] firebase::Future result = - auth->CreateUserWithEmailAndPassword(email, password); + auth->CreateUserWithEmailAndPassword_DEPRECATED(email, password); // [END auth_create_user] (void)result; } @@ -129,14 +129,14 @@ void VariousSignIns(firebase::auth::Auth* auth) { firebase::auth::OAuthProvider::GetCredential( "apple.com", apple_id_token, raw_nonce, nullptr); firebase::Future result = - auth->SignInWithCredential(credential); + auth->SignInWithCredential_DEPRECATED(credential); // [END auth_sign_in_apple] (void)result; } { // [START auth_sign_in_email] firebase::Future result = - auth->SignInWithEmailAndPassword(email, password); + auth->SignInWithEmailAndPassword_DEPRECATED(email, password); // [END auth_sign_in_email] (void)result; } @@ -146,7 +146,7 @@ void VariousSignIns(firebase::auth::Auth* auth) { firebase::auth::GoogleAuthProvider::GetCredential(google_id_token, nullptr); firebase::Future result = - auth->SignInWithCredential(credential); + auth->SignInWithCredential_DEPRECATED(credential); // [END auth_sign_in_google] (void)result; } @@ -156,7 +156,7 @@ void VariousSignIns(firebase::auth::Auth* auth) { firebase::auth::PlayGamesAuthProvider::GetCredential(server_auth_code); firebase::Future result = - auth->SignInWithCredential(credential); + auth->SignInWithCredential_DEPRECATED(credential); // [END auth_sign_in_play_games] (void)result; } @@ -165,7 +165,7 @@ void VariousSignIns(firebase::auth::Auth* auth) { firebase::auth::Credential credential = firebase::auth::FacebookAuthProvider::GetCredential(access_token); firebase::Future result = - auth->SignInWithCredential(credential); + auth->SignInWithCredential_DEPRECATED(credential); // [END auth_sign_in_facebook] (void)result; } @@ -174,7 +174,7 @@ void VariousSignIns(firebase::auth::Auth* auth) { firebase::auth::Credential credential = firebase::auth::GitHubAuthProvider::GetCredential(token); firebase::Future result = - auth->SignInWithCredential(credential); + auth->SignInWithCredential_DEPRECATED(credential); // [END auth_sign_in_github] (void)result; } @@ -183,20 +183,20 @@ void VariousSignIns(firebase::auth::Auth* auth) { firebase::auth::Credential credential = firebase::auth::TwitterAuthProvider::GetCredential(token, secret); firebase::Future result = - auth->SignInWithCredential(credential); + auth->SignInWithCredential_DEPRECATED(credential); // [END auth_sign_in_twitter] (void)result; } { // [START auth_sign_in_custom_token] firebase::Future result = - auth->SignInWithCustomToken(custom_token); + auth->SignInWithCustomToken_DEPRECATED(custom_token); // [END auth_sign_in_custom_token] (void)result; } { // [START auth_sign_in_anonymously] - firebase::Future result = auth->SignInAnonymously(); + firebase::Future result = auth->SignInAnonymously_DEPRECATED(); // [END auth_sign_in_anonymously] (void)result; } @@ -220,7 +220,7 @@ void VariousSignInChecks(firebase::auth::Auth* auth) { { // [START auth_sign_in_email_check] firebase::Future result = - auth->SignInWithEmailAndPasswordLastResult(); + auth->SignInWithEmailAndPasswordLastResult_DEPRECATED(); if (result.status() == firebase::kFutureStatusComplete) { if (result.error() == firebase::auth::kAuthErrorNone) { firebase::auth::User* user = *result.result(); @@ -234,7 +234,7 @@ void VariousSignInChecks(firebase::auth::Auth* auth) { { // [START auth_sign_in_credential_check] firebase::Future result = - auth->SignInWithCredentialLastResult(); + auth->SignInWithCredentialLastResult_DEPRECATED(); if (result.status() == firebase::kFutureStatusComplete) { if (result.error() == firebase::auth::kAuthErrorNone) { firebase::auth::User* user = *result.result(); @@ -262,7 +262,7 @@ void VariousSignInChecks(firebase::auth::Auth* auth) { { // [START auth_sign_in_anonymously_check] firebase::Future result = - auth->SignInAnonymouslyLastResult(); + auth->SignInAnonymouslyLastResult_DEPRECATED(); if (result.status() == firebase::kFutureStatusComplete) { if (result.error() == firebase::auth::kAuthErrorNone) { firebase::auth::User* user = *result.result(); @@ -279,7 +279,7 @@ void VariousSignInChecks(firebase::auth::Auth* auth) { class MyAuthStateListener : public firebase::auth::AuthStateListener { public: void OnAuthStateChanged(firebase::auth::Auth* auth) override { - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); if (user != nullptr) { // User is signed in printf("OnAuthStateChanged: signed_in %s\n", user->uid().c_str()); @@ -303,7 +303,7 @@ void VariousUserManagementChecks(firebase::auth::Auth* auth) { } { // [START auth_user_info_check] - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); if (user != nullptr) { std::string name = user->display_name(); std::string email = user->email(); @@ -317,7 +317,7 @@ void VariousUserManagementChecks(firebase::auth::Auth* auth) { } { // [START auth_user_profile_data_check] - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); if (user != nullptr) { for (auto it = user->provider_data().begin(); it != user->provider_data().end(); ++it) { @@ -338,7 +338,7 @@ void VariousUserManagementChecks(firebase::auth::Auth* auth) { } { // [START auth_profile_edit_check] - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); if (user != nullptr) { firebase::auth::User::UserProfile profile; profile.display_name = "Jane Q. User"; @@ -356,7 +356,7 @@ void VariousUserManagementChecks(firebase::auth::Auth* auth) { } { // [START auth_set_email_check] - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); if (user != nullptr) { user->UpdateEmail("user@example.com") .OnCompletion( @@ -373,7 +373,7 @@ void VariousUserManagementChecks(firebase::auth::Auth* auth) { } { // [START auth_user_verify_email_check] - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); if (user != nullptr) { user->SendEmailVerification().OnCompletion( [](const firebase::Future& completed_future, void* user_data) { @@ -388,7 +388,7 @@ void VariousUserManagementChecks(firebase::auth::Auth* auth) { } { // [START auth_user_update_password_check] - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); std::string newPassword = "SOME-SECURE-PASSWORD"; if (user != nullptr) { @@ -427,7 +427,7 @@ void VariousUserManagementChecks(firebase::auth::Auth* auth) { } { // [START auth_user_delete_check] - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); if (user != nullptr) { user->Delete().OnCompletion( [](const firebase::Future& completed_future, void* user_data) { @@ -445,7 +445,7 @@ void VariousUserManagementChecks(firebase::auth::Auth* auth) { } { // [START auth_user_reauthenticate_check] - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); // Get auth credentials from the user for re-authentication. The example // below shows email and password credentials but there are multiple @@ -530,7 +530,7 @@ void LinkCredential(const firebase::auth::Credential& credential, firebase::auth::Auth* auth) { // [START user_link] // Link the new credential to the currently active user. - firebase::auth::User* current_user = auth->current_user(); + firebase::auth::User* current_user = auth->current_user_DEPRECATED(); firebase::Future result = current_user->LinkWithCredential(credential); // [END user_link] @@ -539,7 +539,7 @@ void LinkCredential(const firebase::auth::Credential& credential, void UnLinkCredential(const char* providerId, firebase::auth::Auth* auth) { // [START user_unlink] // Unlink the sign-in provider from the currently active user. - firebase::auth::User* current_user = auth->current_user(); + firebase::auth::User* current_user = auth->current_user_DEPRECATED(); firebase::Future result = current_user->Unlink(providerId); // [END user_unlink] @@ -549,7 +549,7 @@ void LinkCredentialFailAppleSignIn(const firebase::auth::Credential& credential, firebase::auth::Auth* auth) { // [START link_credential_apple_signin] firebase::Future link_result = - auth->current_user()->LinkAndRetrieveDataWithCredential(credential); + auth->current_user_DEPRECATED()->LinkAndRetrieveDataWithCredential(credential); // To keep example simple, wait on the current thread until call completes. while (link_result.status() == firebase::kFutureStatusPending) { @@ -563,7 +563,7 @@ void LinkCredentialFailAppleSignIn(const firebase::auth::Credential& credential, firebase::auth::kAuthErrorCredentialAlreadyInUse && link_result.result()->info.updated_credential.is_valid()) { // Sign In with the new credential - firebase::Future result = auth->SignInWithCredential( + firebase::Future result = auth->SignInWithCredential_DEPRECATED( link_result.result()->info.updated_credential); } else { // Another link error occurred. @@ -575,7 +575,7 @@ void MergeCredentials(const firebase::auth::Credential& credential, firebase::auth::Auth* auth) { // [START user_merge] // Gather data for the currently signed in User. - firebase::auth::User* current_user = auth->current_user(); + firebase::auth::User* current_user = auth->current_user_DEPRECATED(); std::string current_email = current_user->email(); std::string current_provider_id = current_user->provider_id(); std::string current_display_name = current_user->display_name(); @@ -583,7 +583,7 @@ void MergeCredentials(const firebase::auth::Credential& credential, // Sign in with the new credentials. firebase::Future result = - auth->SignInWithCredential(credential); + auth->SignInWithCredential_DEPRECATED(credential); // To keep example simple, wait on the current thread until call completes. while (result.status() == firebase::kFutureStatusPending) { @@ -608,7 +608,7 @@ void MergeCredentials(const firebase::auth::Credential& credential, void NextSteps(firebase::auth::Auth* auth) { // [START next_steps] - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); if (user != nullptr) { std::string name = user->display_name(); std::string email = user->email(); @@ -623,7 +623,7 @@ void NextSteps(firebase::auth::Auth* auth) { void SendIdTokenToBackend(firebase::auth::Auth* auth) { // [START send_id_token_to_backend] - firebase::auth::User* user = auth->current_user(); + firebase::auth::User* user = auth->current_user_DEPRECATED(); if (user != nullptr) { firebase::Future idToken = user->GetToken(true); @@ -640,7 +640,7 @@ firebase::auth::Auth* AuthOverview(firebase::App* app) { // Request anonymous sign-in and wait until asynchronous call completes. firebase::Future sign_in_future = - auth->SignInAnonymously(); + auth->SignInAnonymously_DEPRECATED(); while (sign_in_future.status() == firebase::kFutureStatusPending) { Wait(100); printf("Signing in...\n"); @@ -709,13 +709,13 @@ const char* DisplayIdentityProviders(const char* email, bool SignIn(firebase::auth::Auth* auth) { // Grab the result of the latest sign-in attempt. firebase::Future future = - auth->SignInAnonymouslyLastResult(); + auth->SignInAnonymouslyLastResult_DEPRECATED(); // If we're in a state where we can try to sign in, do so. if (future.status() == firebase::kFutureStatusInvalid || (future.status() == firebase::kFutureStatusComplete && future.error() != firebase::auth::kAuthErrorNone)) { - auth->SignInAnonymously(); + auth->SignInAnonymously_DEPRECATED(); } // We're signed in if the most recent result was successful. diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index 3f71e4a60e..44b2ed92a2 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -67,7 +67,7 @@ using util::JniStringToString; X(SignInWithEmailAndPassword, "signInWithEmailAndPassword", \ "(Ljava/lang/String;Ljava/lang/String;)" \ "Lcom/google/android/gms/tasks/Task;"), \ - X(CreateUserWithEmailAndPassword, "createUserWithEmailAndPassword", \ + X(CreateUserWithEmailAndPassword_DEPRECATED, "createUserWithEmailAndPassword_DEPRECATED", \ "(Ljava/lang/String;Ljava/lang/String;)" \ "Lcom/google/android/gms/tasks/Task;"), \ X(SendPasswordResetEmail, "sendPasswordResetEmail", \ @@ -393,7 +393,7 @@ Future Auth::FetchProvidersForEmail( return MakeFuture(&futures, handle); } -Future Auth::SignInWithCustomToken(const char* token) { +Future Auth::SignInWithCustomToken_DEPRECATED(const char* token) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCustomToken); JNIEnv* env = Env(auth_data_); @@ -412,7 +412,7 @@ Future Auth::SignInWithCustomToken(const char* token) { return MakeFuture(&futures, handle); } -Future Auth::SignInWithCredential(const Credential& credential) { +Future Auth::SignInWithCredential_DEPRECATED(const Credential& credential) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential); JNIEnv* env = Env(auth_data_); @@ -435,7 +435,7 @@ Future Auth::SignInWithCredential(const Credential& credential) { return MakeFuture(&futures, handle); } -Future Auth::SignInAndRetrieveDataWithCredential( +Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential& credential) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc( @@ -459,12 +459,12 @@ Future Auth::SignInAndRetrieveDataWithCredential( return MakeFuture(&futures, handle); } -Future Auth::SignInWithProvider(FederatedAuthProvider* provider) { +Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider* provider) { FIREBASE_ASSERT_RETURN(Future(), provider); return provider->SignIn(auth_data_); } -Future Auth::SignInAnonymously() { +Future Auth::SignInAnonymously_DEPRECATED() { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInAnonymously); JNIEnv* env = Env(auth_data_); @@ -481,7 +481,7 @@ Future Auth::SignInAnonymously() { return MakeFuture(&futures, handle); } -Future Auth::SignInWithEmailAndPassword(const char* email, +Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char* email, const char* password) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = @@ -514,7 +514,7 @@ Future Auth::SignInWithEmailAndPassword(const char* email, return MakeFuture(&futures, handle); } -Future Auth::CreateUserWithEmailAndPassword(const char* email, +Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char* email, const char* password) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = @@ -549,7 +549,7 @@ Future Auth::CreateUserWithEmailAndPassword(const char* email, // It's safe to return a direct pointer to `current_user` because that class // holds nothing but a pointer to AuthData, which never changes. // All User functions that require synchronization go through AuthData's mutex. -User* Auth::current_user() { +User* Auth::current_user_DEPRECATED() { if (!auth_data_) return nullptr; MutexLock lock(auth_data_->future_impl.mutex()); diff --git a/auth/src/android/common_android.cc b/auth/src/android/common_android.cc index b939c76c6b..f1f2587cea 100644 --- a/auth/src/android/common_android.cc +++ b/auth/src/android/common_android.cc @@ -498,7 +498,7 @@ void ReadSignInResult(jobject result, FutureCallbackData* d, SignInResult* sign_in_result = static_cast(void_data); // Return a pointer to the user and gather the additional data. - sign_in_result->user = d->auth_data->auth->current_user(); + sign_in_result->user = d->auth_data->auth->current_user_DEPRECATED(); ReadAdditionalUserInfo(env, j_additional_user_info, &sign_in_result->info); env->DeleteLocalRef(j_additional_user_info); } @@ -526,7 +526,7 @@ void ReadUserFromSignInResult(jobject result, FutureCallbackData* d, // Return a pointer to the current user, if the current user is valid. User** user_ptr = static_cast(void_data); - *user_ptr = d->auth_data->auth->current_user(); + *user_ptr = d->auth_data->auth->current_user_DEPRECATED(); } } // namespace auth diff --git a/auth/src/auth.cc b/auth/src/auth.cc index 0c3cb86035..1edce34faf 100644 --- a/auth/src/auth.cc +++ b/auth/src/auth.cc @@ -227,7 +227,7 @@ void Auth::AddAuthStateListener(AuthStateListener* listener) { // If the listener is registered successfully and persistent cache has been // loaded, trigger OnAuthStateChanged() immediately. Otherwise, wait until // the cache is loaded, through AuthStateListener event. - // NOTE: This should be called synchronously or current_user() for desktop + // NOTE: This should be called synchronously or current_user_DEPRECATED() for desktop // implementation may not work. if (added && !auth_data_->persistent_cache_load_pending) { listener->OnAuthStateChanged(this); @@ -364,12 +364,12 @@ AUTH_NOTIFY_LISTENERS(NotifyIdTokenListeners, "ID token", id_token_listeners, OnIdTokenChanged); AUTH_RESULT_FN(Auth, FetchProvidersForEmail, Auth::FetchProvidersResult) -AUTH_RESULT_FN(Auth, SignInWithCustomToken, User*) -AUTH_RESULT_FN(Auth, SignInWithCredential, User*) -AUTH_RESULT_FN(Auth, SignInAndRetrieveDataWithCredential, SignInResult) -AUTH_RESULT_FN(Auth, SignInAnonymously, User*) -AUTH_RESULT_FN(Auth, SignInWithEmailAndPassword, User*) -AUTH_RESULT_FN(Auth, CreateUserWithEmailAndPassword, User*) +AUTH_RESULT_FN(Auth, SignInWithCustomToken_DEPRECATED, User*) +AUTH_RESULT_FN(Auth, SignInWithCredential_DEPRECATED, User*) +AUTH_RESULT_FN(Auth, SignInAndRetrieveDataWithCredential_DEPRECATED, SignInResult) +AUTH_RESULT_FN(Auth, SignInAnonymously_DEPRECATED, User*) +AUTH_RESULT_FN(Auth, SignInWithEmailAndPassword_DEPRECATED, User*) +AUTH_RESULT_FN(Auth, CreateUserWithEmailAndPassword_DEPRECATED, User*) AUTH_RESULT_FN(Auth, SendPasswordResetEmail, void) } // namespace auth diff --git a/auth/src/data.h b/auth/src/data.h index 797a680148..3d33719879 100644 --- a/auth/src/data.h +++ b/auth/src/data.h @@ -32,13 +32,13 @@ namespace auth { enum AuthApiFunction { // External functions in the Auth API. kAuthFn_FetchProvidersForEmail, - kAuthFn_SignInWithCustomToken, - kAuthFn_SignInWithCredential, - kAuthFn_SignInAndRetrieveDataWithCredential, - kAuthFn_SignInAnonymously, - kAuthFn_SignInWithEmailAndPassword, - kAuthFn_SignInWithProvider, - kAuthFn_CreateUserWithEmailAndPassword, + kAuthFn_SignInWithCustomToken_DEPRECATED, + kAuthFn_SignInWithCredential_DEPRECATED, + kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED, + kAuthFn_SignInAnonymously_DEPRECATED, + kAuthFn_SignInWithEmailAndPassword_DEPRECATED, + kAuthFn_SignInWithProvider_DEPRECATED, + kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED, kAuthFn_SendPasswordResetEmail, // External functions in the User API. @@ -46,16 +46,16 @@ enum AuthApiFunction { kUserFn_UpdateEmail, kUserFn_UpdatePassword, kUserFn_Reauthenticate, - kUserFn_ReauthenticateAndRetrieveData, + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED, kUserFn_SendEmailVerification, kUserFn_ConfirmEmailVerification, kUserFn_UpdateUserProfile, - kUserFn_LinkWithCredential, + kUserFn_LinkWithCredential_DEPRECATED, kUserFn_LinkAndRetrieveDataWithCredential, - kUserFn_LinkWithProvider, - kUserFn_ReauthenticateWithProvider, - kUserFn_Unlink, - kUserFn_UpdatePhoneNumberCredential, + kUserFn_LinkWithProvider_DEPRECATED, + kUserFn_ReauthenticateWithProvider_DEPRECATED, + kUserFn_Unlink_DEPRECATED, + kUserFn_UpdatePhoneNumberCredential_DEPRECATED, kUserFn_Reload, kUserFn_Delete, diff --git a/auth/src/desktop/auth_desktop.cc b/auth/src/desktop/auth_desktop.cc index b7fcf763a5..bcbd13bd3d 100644 --- a/auth/src/desktop/auth_desktop.cc +++ b/auth/src/desktop/auth_desktop.cc @@ -111,7 +111,7 @@ void IdTokenRefreshListener::OnIdTokenChanged(Auth* auth) { // to prevent deadlocks! MutexLock lock(mutex_); MutexLock future_lock(auth->auth_data_->future_impl.mutex()); - if (auth->current_user()) { + if (auth->current_user_DEPRECATED()) { ResetTokenRefreshCounter(auth->auth_data_); // Retrieve id_token from auth_data @@ -151,7 +151,7 @@ bool Auth::GetAuthTokenForRegistry(App* app, void* /*unused*/, void* out) { Auth* auth = Auth::FindAuth(app); if (auth) { // Make sure the persistent cache is loaded. - auth->current_user(); + auth->current_user_DEPRECATED(); auto result = static_cast(out); MutexLock lock(auth->auth_data_->token_listener_mutex); @@ -176,7 +176,7 @@ bool Auth::GetAuthTokenAsyncForRegistry(App* app, void* force_refresh, Auth* auth = Auth::FindAuth(app); if (auth) { - User* user = auth->current_user(); + User* user = auth->current_user_DEPRECATED(); if (user) { Future future = user->GetTokenInternal( *in_force_refresh, kInternalFn_GetTokenForFunctionRegistry); @@ -199,7 +199,7 @@ bool Auth::GetCurrentUserUidForRegistry(App* app, void* /*unused*/, void* out) { Auth* auth = Auth::FindAuth(app); if (!auth) return false; - User* user = auth->current_user(); + User* user = auth->current_user_DEPRECATED(); if (!user) return false; if (out_string) { @@ -337,7 +337,7 @@ void Auth::DestroyPlatformAuth(AuthData* const auth_data) { // RPCs -Future Auth::SignInWithCustomToken(const char* const custom_token) { +Future Auth::SignInWithCustomToken_DEPRECATED(const char* const custom_token) { Promise promise(&auth_data_->future_impl, kAuthFn_SignInWithCustomToken); if (!custom_token || strlen(custom_token) == 0) { @@ -355,7 +355,7 @@ Future Auth::SignInWithCustomToken(const char* const custom_token) { PerformSignInFlow); } -Future Auth::SignInWithCredential(const Credential& credential) { +Future Auth::SignInWithCredential_DEPRECATED(const Credential& credential) { Promise promise(&auth_data_->future_impl, kAuthFn_SignInWithCredential); if (!ValidateCredential(&promise, credential.provider(), credential.impl_)) { @@ -366,7 +366,7 @@ Future Auth::SignInWithCredential(const Credential& credential) { credential.impl_); } -Future Auth::SignInWithProvider(FederatedAuthProvider* provider) { +Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider* provider) { FIREBASE_ASSERT_RETURN(Future(), provider); // TODO(b/139363200) // return provider->SignIn(auth_data_); @@ -381,7 +381,7 @@ Future Auth::SignInWithProvider(FederatedAuthProvider* provider) { return MakeFuture(&auth_data_->future_impl, handle); } -Future Auth::SignInAnonymously() { +Future Auth::SignInAnonymously_DEPRECATED() { Promise promise(&auth_data_->future_impl, kAuthFn_SignInAnonymously); // If user is already signed in anonymously, return immediately. @@ -405,7 +405,7 @@ Future Auth::SignInAnonymously() { PerformSignInFlow); } -Future Auth::SignInWithEmailAndPassword(const char* const email, +Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char* const email, const char* const password) { Promise promise(&auth_data_->future_impl, kAuthFn_SignInWithEmailAndPassword); @@ -421,7 +421,7 @@ Future Auth::SignInWithEmailAndPassword(const char* const email, PerformSignInFlow); } -Future Auth::CreateUserWithEmailAndPassword(const char* const email, +Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char* const email, const char* const password) { Promise promise(&auth_data_->future_impl, kAuthFn_CreateUserWithEmailAndPassword); @@ -438,7 +438,7 @@ Future Auth::CreateUserWithEmailAndPassword(const char* const email, PerformSignInFlow); } -Future Auth::SignInAndRetrieveDataWithCredential( +Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential& credential) { Promise promise(&auth_data_->future_impl, kAuthFn_SignInAndRetrieveDataWithCredential); @@ -509,7 +509,7 @@ void Auth::SignOut() { AuthenticationResult::SignOut(auth_data_); } -// AuthStateListener to wait for current_user() until persistent cache load is +// AuthStateListener to wait for current_user_DEPRECATED() until persistent cache load is // finished. class CurrentUserBlockListener : public firebase::auth::AuthStateListener { public: @@ -527,7 +527,7 @@ class CurrentUserBlockListener : public firebase::auth::AuthStateListener { // It's safe to return a direct pointer to `current_user` because that class // holds nothing but a pointer to AuthData, which never changes. // All User functions that require synchronization go through AuthData's mutex. -User* Auth::current_user() { +User* Auth::current_user_DEPRECATED() { if (!auth_data_) return nullptr; // Add a listener and wait for the first trigger. diff --git a/auth/src/desktop/authentication_result.cc b/auth/src/desktop/authentication_result.cc index b8252e9ebe..f28798744b 100644 --- a/auth/src/desktop/authentication_result.cc +++ b/auth/src/desktop/authentication_result.cc @@ -45,7 +45,7 @@ SignInResult AuthenticationResult::SetAsCurrentUser( // Save the previous user state to be able to check whether listeners should // be notified later on. UserData previous_user; - // Don't call Auth::current_user() to avoid locking the mutex twice. + // Don't call Auth::current_user_DEPRECATED() to avoid locking the mutex twice. User* api_user_to_return = nullptr; { UserView::Writer writer = diff --git a/auth/src/desktop/user_desktop.cc b/auth/src/desktop/user_desktop.cc index d70eb76d66..f066b0c097 100644 --- a/auth/src/desktop/user_desktop.cc +++ b/auth/src/desktop/user_desktop.cc @@ -105,7 +105,7 @@ GetTokenResult GetTokenIfFresh(const UserView::Reader& user, return GetTokenResult(kAuthErrorFailure); } -// Makes sure that calling auth->current_user()->id_token() will result in +// Makes sure that calling auth->current_user_DEPRECATED()->id_token() will result in // a token that is good for at least 5 minutes. Will fetch a new token from the // backend if necessary. // @@ -426,7 +426,7 @@ UserDataPersist::UserDataPersist( : user_secure_manager_(std::move(user_secure_manager)) {} void UserDataPersist::OnAuthStateChanged(Auth* auth) { // NOLINT - if (auth->current_user() != nullptr) { + if (auth->current_user_DEPRECATED() != nullptr) { SaveUserData(auth->auth_data_); } else { DeleteUserData(auth->auth_data_); diff --git a/auth/src/include/firebase/auth.h b/auth/src/include/firebase/auth.h index 408c34ea90..015a12197f 100644 --- a/auth/src/include/firebase/auth.h +++ b/auth/src/include/firebase/auth.h @@ -102,7 +102,7 @@ struct SignInResult; /// /// // Request anonymous sign-in and wait until asynchronous call completes. /// firebase::Future sign_in_future = -/// auth->SignInAnonymously(); +/// auth->SignInAnonymously_DEPRECATED(); /// while(sign_in_future.status() == firebase::kFutureStatusPending) { /// // when polling, like this, make sure you service your platform's /// // message loop @@ -146,6 +146,8 @@ class Auth { ~Auth(); + /// @deprecated This is a deprecated method. Please use @current_user instead. + /// /// Synchronously gets the cached current user, or nullptr if there is none. /// @note This function may block and wait until the Auth instance finishes /// loading the saved user's state. This should only happen for a short @@ -160,7 +162,7 @@ class Auth { /// /// @endxmlonly /// - User* current_user(); + FIREBASE_DEPRECATED User* current_user_DEPRECATED(); /// The current user language code. This can be set to the app’s current /// language by calling set_language_code. The string must be a language code @@ -238,23 +240,33 @@ class Auth { /// Get results of the most recent call to @ref FetchProvidersForEmail. Future FetchProvidersForEmailLastResult() const; - // ----- Sign In --------------------------------------------------------- + /// @deprecated This is a deprecated method. Please use @SignInWithCustomToken instead. + /// /// Asynchronously logs into Firebase with the given Auth token. /// /// An error is returned, if the token is invalid, expired or otherwise /// not accepted by the server. - Future SignInWithCustomToken(const char* token); + FIREBASE_DEPRECATED Future SignInWithCustomToken_DEPRECATED(const char* token); + /// @deprecated + /// /// Get results of the most recent call to @ref SignInWithCustomToken. - Future SignInWithCustomTokenLastResult() const; + FIREBASE_DEPRECATED Future SignInWithCustomTokenLastResult_DEPRECATED() const; + /// @deprecated This is a deprecated method. Please use @SignInWithCredential + /// instead. + /// /// Convenience method for @ref SignInAndRetrieveDataWithCredential that /// doesn't return additional identity provider data. - Future SignInWithCredential(const Credential& credential); + FIREBASE_DEPRECATED Future SignInWithCredential_DEPRECATED(const Credential& credential); - /// Get results of the most recent call to @ref SignInWithCredential. - Future SignInWithCredentialLastResult() const; + /// @deprecated + /// + /// Get results of the most recent call to @ref SignInWithCredential_DEPRECATED. + FIREBASE_DEPRECATED Future SignInWithCredentialLastResult_DEPRECATED() const; + /// @deprecated This is a deprecated method. Please use @SignInWithProvider instead. + /// /// Sign-in a user authenticated via a federated auth provider. /// /// @param[in] provider Contains information on the provider to authenticate @@ -265,8 +277,10 @@ class Auth { /// @note: This operation is supported only on iOS, tvOS and Android /// platforms. On other platforms this method will return a Future with a /// preset error code: kAuthErrorUnimplemented. - Future SignInWithProvider(FederatedAuthProvider* provider); + FIREBASE_DEPRECATED Future SignInWithProvider_DEPRCATED(FederatedAuthProvider* provider); + /// @deprecated This is a deprecated method. Please use @SignInAndRetrieveDataWithCredential instead. + /// /// Asynchronously logs into Firebase with the given credentials. /// /// For example, the credential could wrap a Facebook login access token or @@ -278,13 +292,18 @@ class Auth { /// /// An error is returned if the token is invalid, expired, or otherwise not /// accepted by the server. - Future SignInAndRetrieveDataWithCredential( + FIREBASE_DEPRECATED Future SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential& credential); + /// @deprecated + /// /// Get results of the most recent call to - /// @ref SignInAndRetrieveDataWithCredential. - Future SignInAndRetrieveDataWithCredentialLastResult() const; + /// @ref SignInAndRetrieveDataWithCredential_DEPRECATED. + FIREBASE_DEPRECATED Future SignInAndRetrieveDataWithCredentialLastResult_DEPRECATED() const; + /// @deprecated This is a deprecated method. Please use @SignInAnonymously + /// instead. + /// /// Asynchronously creates and becomes an anonymous user. /// If there is already an anonymous user signed in, that user will be /// returned instead. @@ -329,7 +348,7 @@ class Auth { /// if (future.status() == firebase::kFutureStatusInvalid || /// (future.status() == firebase::kFutureStatusComplete && /// future.error() != firebase::auth::kAuthErrorNone)) { - /// auth.SignInAnonymously(); + /// auth.SignInAnonymously_DEPRECATED(); /// } /// /// // We're signed in if the most recent result was successful. @@ -338,31 +357,39 @@ class Auth { /// } /// @endcode /// @endif - Future SignInAnonymously(); + Future SignInAnonymously_DEPRECATED(); - /// Get results of the most recent call to @ref SignInAnonymously. - Future SignInAnonymouslyLastResult() const; + /// Get results of the most recent call to @ref SignInAnonymously_DEPRECATED. + Future SignInAnonymouslyLastResult_DEPRECATED() const; + /// @deprecated This is a deprecated method. Please use @SignInWithEmailAndPassword + /// instead. + /// /// Signs in using provided email address and password. /// An error is returned if the password is wrong or otherwise not accepted /// by the server. - Future SignInWithEmailAndPassword(const char* email, + FIREBASE_DEPRECATED Future SignInWithEmailAndPassword_DEPRECATED(const char* email, const char* password); - /// Get results of the most recent call to @ref SignInWithEmailAndPassword. - Future SignInWithEmailAndPasswordLastResult() const; + /// @deprecated + /// + /// Get results of the most recent call to @ref SignInWithEmailAndPassword_DEPRECATED. + Future SignInWithEmailAndPasswordLastResult_DEPRECATED() const; + /// @deprecated This is a deprecated method. Please use @CreateUserWithEmailAndPassword + /// instead. + /// /// Creates, and on success, logs in a user with the given email address /// and password. /// /// An error is returned when account creation is unsuccessful /// (due to another existing account, invalid password, etc.). - Future CreateUserWithEmailAndPassword(const char* email, + FIREBASE_DEPRECATED Future CreateUserWithEmailAndPassword_DEPRECATED(const char* email, const char* password); /// Get results of the most recent call to - /// @ref CreateUserWithEmailAndPassword. - Future CreateUserWithEmailAndPasswordLastResult() const; + /// @ref CreateUserWithEmailAndPassword_DEPRECATED. + FIREBASE_DEPRECATED Future CreateUserWithEmailAndPasswordLastResult_DEPRECATED() const; /// Removes any existing authentication credentials from this client. /// This function always succeeds. @@ -551,7 +578,7 @@ class Auth { void* out_future); // Provides access to the current user's uid, equivalent to calling - // this->current_user()->uid(). Returns the current user's uid or an empty + // this->current_user_DEPRECATED()->uid(). Returns the current user's uid or an empty // string, if there isn't one. The out pointer is expected to point to an // instance of std::string. static bool GetCurrentUserUidForRegistry(App* app, void* /*unused*/, diff --git a/auth/src/ios/auth_ios.mm b/auth/src/ios/auth_ios.mm index 01ab3d160f..d3fce962d2 100644 --- a/auth/src/ios/auth_ios.mm +++ b/auth/src/ios/auth_ios.mm @@ -258,7 +258,7 @@ void LogHeartbeat(Auth *auth) { // It's safe to return a direct pointer to `current_user` because that class // holds nothing but a pointer to AuthData, which never changes. // All User functions that require synchronization go through AuthData's mutex. -User *Auth::current_user() { +User *Auth::current_user_DEPRECATED() { if (!auth_data_) return nullptr; MutexLock lock(auth_data_->future_impl.mutex()); @@ -360,7 +360,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu util::NSStringToString(error.localizedDescription).c_str(), result); } -Future Auth::SignInWithCustomToken(const char *token) { +Future Auth::SignInWithCustomToken_DEPRECATED(const char *token) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCustomToken, nullptr); @@ -373,7 +373,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu return MakeFuture(&futures, handle); } -Future Auth::SignInWithCredential(const Credential &credential) { +Future Auth::SignInWithCredential_DEPRECATED(const Credential &credential) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential, nullptr); @@ -386,7 +386,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu return MakeFuture(&futures, handle); } -Future Auth::SignInAndRetrieveDataWithCredential(const Credential &credential) { +Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED(const Credential &credential) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInAndRetrieveDataWithCredential, SignInResult()); @@ -400,12 +400,12 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu return MakeFuture(&futures, handle); } -Future Auth::SignInWithProvider(FederatedAuthProvider *provider) { +Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider *provider) { FIREBASE_ASSERT_RETURN(Future(), provider); return provider->SignIn(auth_data_); } -Future Auth::SignInAnonymously() { +Future Auth::SignInAnonymously_DEPRECATED() { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = auth_data_->future_impl.SafeAlloc(kAuthFn_SignInAnonymously, nullptr); @@ -417,7 +417,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu return MakeFuture(&futures, handle); } -Future Auth::SignInWithEmailAndPassword(const char *email, const char *password) { +Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword, nullptr); if (!email || strlen(email) == 0) { @@ -435,7 +435,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu return MakeFuture(&futures, handle); } -Future Auth::CreateUserWithEmailAndPassword(const char *email, const char *password) { +Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword, nullptr); if (!email || strlen(email) == 0) { diff --git a/auth/src_java/fake/com/google/firebase/auth/FirebaseAuth.java b/auth/src_java/fake/com/google/firebase/auth/FirebaseAuth.java index 3dabb3aa90..c1ee9b1193 100644 --- a/auth/src_java/fake/com/google/firebase/auth/FirebaseAuth.java +++ b/auth/src_java/fake/com/google/firebase/auth/FirebaseAuth.java @@ -186,7 +186,7 @@ public Task signInWithCredential(AuthCredential credential) { return signInHelper("FirebaseAuth.signInWithCredential"); } - public Task signInAnonymously() { + public Task signInAnonymously_DEPRECATED() { return signInHelper("FirebaseAuth.signInAnonymously"); } @@ -227,8 +227,8 @@ public Task startActivityForSignInWithProvider( return signInHelper("FirebaseAuth.startActivityForSignInWithProvider"); } - public Task createUserWithEmailAndPassword(String email, String password) { - return signInHelper("FirebaseAuth.createUserWithEmailAndPassword"); + public Task createUserWithEmailAndPassword_DEPRECATED(String email, String password) { + return signInHelper("FirebaseAuth.createUserWithEmailAndPassword_DEPRECATED"); } public Task sendPasswordResetEmail(String email) { diff --git a/auth/tests/auth_test.cc b/auth/tests/auth_test.cc index e14778a32b..24b774dae2 100644 --- a/auth/tests/auth_test.cc +++ b/auth/tests/auth_test.cc @@ -124,7 +124,7 @@ class AuthTest : public ::testing::Test { void MakeAuth() { firebase_app_ = testing::CreateApp(); firebase_auth_ = Auth::GetAuth(firebase_app_); - if (firebase_auth_->current_user()) { + if (firebase_auth_->current_user_DEPRECATED()) { firebase_auth_->SignOut(); } } @@ -231,7 +231,7 @@ TEST_F(AuthTest, TestSignInWithCustomTokenSucceeded) { " ]" "}"); MakeAuth(); - Future result = firebase_auth_->SignInWithCustomToken("its-a-token"); + Future result = firebase_auth_->SignInWithCustomToken_DEPRECATED("its-a-token"); Verify(kAuthErrorNone, result); } @@ -260,7 +260,7 @@ TEST_F(AuthTest, TestSignInWithCredentialSucceeded) { "}"); MakeAuth(); Credential credential = EmailAuthProvider::GetCredential("abc@g.com", "abc"); - Future result = firebase_auth_->SignInWithCredential(credential); + Future result = firebase_auth_->SignInWithCredential_DEPRECATED(credential); Verify(kAuthErrorNone, result); } @@ -288,7 +288,7 @@ TEST_F(AuthTest, TestSignInAnonymouslySucceeded) { " ]" "}"); MakeAuth(); - Future result = firebase_auth_->SignInAnonymously(); + Future result = firebase_auth_->SignInAnonymously_DEPRECATED(); Verify(kAuthErrorNone, result); } @@ -317,7 +317,7 @@ TEST_F(AuthTest, TestSignInWithEmailAndPasswordSucceeded) { "}"); MakeAuth(); Future result = - firebase_auth_->SignInWithEmailAndPassword("abc@xyz.com", "password"); + firebase_auth_->SignInWithEmailAndPassword_DEPRECATED("abc@xyz.com", "password"); Verify(kAuthErrorNone, result); } @@ -325,7 +325,7 @@ TEST_F(AuthTest, TestCreateUserWithEmailAndPasswordSucceeded) { firebase::testing::cppsdk::ConfigSet( "{" " config:[" - " {fake:'FirebaseAuth.createUserWithEmailAndPassword'," + " {fake:'FirebaseAuth.createUserWithEmailAndPassword_DEPRECATED'," " futuregeneric:{ticker:1}}," " {fake:'FIRAuth.createUserWithEmail:password:completion:'," " futuregeneric:{ticker:1}}," @@ -346,7 +346,7 @@ TEST_F(AuthTest, TestCreateUserWithEmailAndPasswordSucceeded) { "}"); MakeAuth(); Future result = - firebase_auth_->CreateUserWithEmailAndPassword("abc@xyz.com", "password"); + firebase_auth_->CreateUserWithEmailAndPassword_DEPRECATED("abc@xyz.com", "password"); Verify(kAuthErrorNone, result); } @@ -375,7 +375,7 @@ TEST_F(AuthTest, TestSignInWithCustomTokenFailed) { " ]" "}"); MakeAuth(); - Future result = firebase_auth_->SignInWithCustomToken("its-a-token"); + Future result = firebase_auth_->SignInWithCustomToken_DEPRECATED("its-a-token"); Verify(kAuthErrorInvalidCustomToken, result); } @@ -399,7 +399,7 @@ TEST_F(AuthTest, TestSignInWithCredentialFailed) { "}"); MakeAuth(); Credential credential = EmailAuthProvider::GetCredential("abc@g.com", "abc"); - Future result = firebase_auth_->SignInWithCredential(credential); + Future result = firebase_auth_->SignInWithCredential_DEPRECATED(credential); Verify(kAuthErrorInvalidEmail, result); } @@ -422,7 +422,7 @@ TEST_F(AuthTest, TestSignInAnonymouslyFailed) { " ]" "}"); MakeAuth(); - Future result = firebase_auth_->SignInAnonymously(); + Future result = firebase_auth_->SignInAnonymously_DEPRECATED(); Verify(kAuthErrorOperationNotAllowed, result); } @@ -446,7 +446,7 @@ TEST_F(AuthTest, TestSignInWithEmailAndPasswordFailed) { "}"); MakeAuth(); Future result = - firebase_auth_->SignInWithEmailAndPassword("abc@xyz.com", "password"); + firebase_auth_->SignInWithEmailAndPassword_DEPRECATED("abc@xyz.com", "password"); Verify(kAuthErrorWrongPassword, result); } @@ -454,7 +454,7 @@ TEST_F(AuthTest, TestCreateUserWithEmailAndPasswordFailed) { firebase::testing::cppsdk::ConfigSet( "{" " config:[" - " {fake:'FirebaseAuth.createUserWithEmailAndPassword'," + " {fake:'FirebaseAuth.createUserWithEmailAndPassword_DEPRECATED'," " futuregeneric:{throwexception:true," " " "exceptionmsg:'[FirebaseAuthUserCollisionException:ERROR_EMAIL_ALREADY_" @@ -470,7 +470,7 @@ TEST_F(AuthTest, TestCreateUserWithEmailAndPasswordFailed) { "}"); MakeAuth(); Future result = - firebase_auth_->CreateUserWithEmailAndPassword("abc@xyz.com", "password"); + firebase_auth_->CreateUserWithEmailAndPassword_DEPRECATED("abc@xyz.com", "password"); Verify(kAuthErrorEmailAlreadyInUse, result); } @@ -504,16 +504,16 @@ TEST_F(AuthTest, TestCurrentUserAndSignOut) { MakeAuth(); // No user is signed in. - EXPECT_EQ(nullptr, firebase_auth_->current_user()); + EXPECT_EQ(nullptr, firebase_auth_->current_user_DEPRECATED()); // Now sign-in, say anonymously. - Future result = firebase_auth_->SignInAnonymously(); + Future result = firebase_auth_->SignInAnonymously_DEPRECATED(); MaybeWaitForFuture(result); - EXPECT_NE(nullptr, firebase_auth_->current_user()); + EXPECT_NE(nullptr, firebase_auth_->current_user_DEPRECATED()); // Now sign-out. firebase_auth_->SignOut(); - EXPECT_EQ(nullptr, firebase_auth_->current_user()); + EXPECT_EQ(nullptr, firebase_auth_->current_user_DEPRECATED()); } TEST_F(AuthTest, TestSendPasswordResetEmailSucceeded) { diff --git a/auth/tests/desktop/auth_desktop_test.cc b/auth/tests/desktop/auth_desktop_test.cc index d261d52147..5052182269 100644 --- a/auth/tests/desktop/auth_desktop_test.cc +++ b/auth/tests/desktop/auth_desktop_test.cc @@ -271,7 +271,7 @@ class AuthDesktopTest : public ::testing::Test { InitializeSignInWithProviderFakes(CreateGetAccountInfoFake()); provider->SetProviderData(GetFakeOAuthProviderData()); provider->SetAuthHandler(handler); - Future future = firebase_auth_->SignInWithProvider(provider); + Future future = firebase_auth_->SignInWithProvider_DEPRECATED(provider); if (trigger_sign_in) { handler->TriggerSignInComplete(); } @@ -287,7 +287,7 @@ class AuthDesktopTest : public ::testing::Test { TEST_F(AuthDesktopTest, TestSignInWithProviderReturnsUnsupportedError) { FederatedOAuthProvider provider; - Future future = firebase_auth_->SignInWithProvider(&provider); + Future future = firebase_auth_->SignInWithProvider_DEPRECATED(&provider); EXPECT_EQ(future.result()->user, nullptr); EXPECT_EQ(future.error(), kAuthErrorUnimplemented); EXPECT_EQ(std::string(future.error_message()), @@ -300,7 +300,7 @@ TEST_F(AuthDesktopTest, OAuthProviderTestHandler handler(/*extra_integrity_checks_=*/true); InitializeSuccessfulSignInWithProviderFlow(&provider, &handler); - Future future = firebase_auth_->SignInWithProvider(&provider); + Future future = firebase_auth_->SignInWithProvider_DEPRECATED(&provider); handler.TriggerSignInComplete(); SignInResult sign_in_result = WaitForFuture(future); } @@ -316,9 +316,9 @@ TEST_F(AuthDesktopTest, OAuthProviderTestHandler handler2; provider2.SetAuthHandler(&handler2); - Future future1 = firebase_auth_->SignInWithProvider(&provider1); + Future future1 = firebase_auth_->SignInWithProvider_DEPRECATED(&provider1); EXPECT_EQ(future1.status(), kFutureStatusPending); - Future future2 = firebase_auth_->SignInWithProvider(&provider2); + Future future2 = firebase_auth_->SignInWithProvider_DEPRECATED(&provider2); VerifySignInResult(future2, kAuthErrorFederatedProviderAreadyInUse); handler1.TriggerSignInComplete(); const SignInResult sign_in_result = WaitForFuture(future1); @@ -500,7 +500,7 @@ TEST_F(AuthDesktopTest, CompleteSignInWithFailedResponse) { // Call the function and verify results. const User* const user = - WaitForFuture(firebase_auth_->SignInAnonymously(), kAuthErrorFailure); + WaitForFuture(firebase_auth_->SignInAnonymously_DEPRECATED(), kAuthErrorFailure); EXPECT_EQ(nullptr, user); } @@ -526,7 +526,7 @@ TEST_F(AuthDesktopTest, CompleteSignInWithGetAccountInfoFailure) { // Call the function and verify results. const User* const user = - WaitForFuture(firebase_auth_->SignInAnonymously(), kAuthErrorFailure); + WaitForFuture(firebase_auth_->SignInAnonymously_DEPRECATED(), kAuthErrorFailure); EXPECT_EQ(nullptr, user); } @@ -556,7 +556,7 @@ TEST_F(AuthDesktopTest, TestSignInAnonymously) { id_token_listener.ExpectChanges(2); auth_state_listener.ExpectChanges(2); - const User* const user = WaitForFuture(firebase_auth_->SignInAnonymously()); + const User* const user = WaitForFuture(firebase_auth_->SignInAnonymously_DEPRECATED()); EXPECT_TRUE(user->is_anonymous()); EXPECT_EQ("localid123", user->uid()); EXPECT_EQ("", user->email()); @@ -585,14 +585,14 @@ TEST_F(AuthDesktopTest, TestSignInWithEmailAndPassword) { auth_state_listener.ExpectChanges(2); // Call the function and verify results. - const Future future = firebase_auth_->SignInWithEmailAndPassword( + const Future future = firebase_auth_->SignInWithEmailAndPassword_DEPRECATED( "testsignin@example.com", "testsignin"); const User* const user = WaitForFuture(future); EXPECT_FALSE(user->is_anonymous()); VerifyUser(*user); } -// Test Auth::CreateUserWithEmailAndPassword. +// Test Auth::CreateUserWithEmailAndPassword_DEPRECATED. TEST_F(AuthDesktopTest, TestCreateUserWithEmailAndPassword) { FakeSetT fakes; @@ -620,7 +620,7 @@ TEST_F(AuthDesktopTest, TestCreateUserWithEmailAndPassword) { id_token_listener.ExpectChanges(2); auth_state_listener.ExpectChanges(2); - const Future future = firebase_auth_->CreateUserWithEmailAndPassword( + const Future future = firebase_auth_->CreateUserWithEmailAndPassword_DEPRECATED( "testsignin@example.com", "testsignin"); const User* const user = WaitForFuture(future); EXPECT_FALSE(user->is_anonymous()); @@ -644,7 +644,7 @@ TEST_F(AuthDesktopTest, TestSignInWithCustomToken) { auth_state_listener.ExpectChanges(2); const User* const user = - WaitForFuture(firebase_auth_->SignInWithCustomToken("fake_custom_token")); + WaitForFuture(firebase_auth_->SignInWithCustomToken_DEPRECATED("fake_custom_token")); EXPECT_FALSE(user->is_anonymous()); VerifyUser(*user); } @@ -660,7 +660,7 @@ TEST_F(AuthDesktopTest, TestSignInWithCredential_GoogleIdToken) { const Credential credential = GoogleAuthProvider::GetCredential("fake_id_token", ""); const User* const user = - WaitForFuture(firebase_auth_->SignInWithCredential(credential)); + WaitForFuture(firebase_auth_->SignInWithCredential_DEPRECATED(credential)); EXPECT_FALSE(user->is_anonymous()); VerifyUser(*user); } @@ -674,7 +674,7 @@ TEST_F(AuthDesktopTest, TestSignInWithCredential_GoogleAccessToken) { const Credential credential = GoogleAuthProvider::GetCredential("", "fake_access_token"); const User* const user = - WaitForFuture(firebase_auth_->SignInWithCredential(credential)); + WaitForFuture(firebase_auth_->SignInWithCredential_DEPRECATED(credential)); EXPECT_FALSE(user->is_anonymous()); VerifyUser(*user); } @@ -692,7 +692,7 @@ TEST_F(AuthDesktopTest, const Credential credential = GoogleAuthProvider::GetCredential("", "fake_access_token"); const User* const user = WaitForFuture( - firebase_auth_->SignInWithCredential(credential), kAuthErrorFailure); + firebase_auth_->SignInWithCredential_DEPRECATED(credential), kAuthErrorFailure); EXPECT_EQ(nullptr, user); } @@ -710,7 +710,7 @@ TEST_F(AuthDesktopTest, const Credential credential = GoogleAuthProvider::GetCredential("", "fake_access_token"); const User* const user = WaitForFuture( - firebase_auth_->SignInWithCredential(credential), kAuthErrorFailure); + firebase_auth_->SignInWithCredential_DEPRECATED(credential), kAuthErrorFailure); EXPECT_EQ(nullptr, user); } @@ -726,7 +726,7 @@ TEST_F(AuthDesktopTest, TestSignInWithCredential_NeedsConfirmation) { const Credential credential = GoogleAuthProvider::GetCredential("fake_id_token", ""); - WaitForFuture(firebase_auth_->SignInWithCredential(credential), + WaitForFuture(firebase_auth_->SignInWithCredential_DEPRECATED(credential), kAuthErrorAccountExistsWithDifferentCredentials); } @@ -744,7 +744,7 @@ TEST_F(AuthDesktopTest, TestSignInAndRetrieveDataWithCredential_GitHub) { const Credential credential = GitHubAuthProvider::GetCredential("fake_access_token"); const SignInResult sign_in_result = WaitForFuture( - firebase_auth_->SignInAndRetrieveDataWithCredential(credential)); + firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED(credential)); EXPECT_FALSE(sign_in_result.user->is_anonymous()); VerifyUser(*sign_in_result.user); @@ -773,7 +773,7 @@ TEST_F(AuthDesktopTest, TestSignInAndRetrieveDataWithCredential_Twitter) { const Credential credential = TwitterAuthProvider::GetCredential( "fake_access_token", "fake_oauth_token"); const SignInResult sign_in_result = WaitForFuture( - firebase_auth_->SignInAndRetrieveDataWithCredential(credential)); + firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED(credential)); EXPECT_FALSE(sign_in_result.user->is_anonymous()); VerifyUser(*sign_in_result.user); @@ -793,7 +793,7 @@ TEST_F(AuthDesktopTest, const Credential credential = TwitterAuthProvider::GetCredential( "fake_access_token", "fake_oauth_token"); const SignInResult sign_in_result = WaitForFuture( - firebase_auth_->SignInAndRetrieveDataWithCredential(credential)); + firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED(credential)); EXPECT_FALSE(sign_in_result.user->is_anonymous()); VerifyUser(*sign_in_result.user); @@ -816,7 +816,7 @@ TEST_F(AuthDesktopTest, const Credential credential = TwitterAuthProvider::GetCredential( "fake_access_token", "fake_oauth_token"); const SignInResult sign_in_result = WaitForFuture( - firebase_auth_->SignInAndRetrieveDataWithCredential(credential)); + firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED(credential)); EXPECT_FALSE(sign_in_result.user->is_anonymous()); VerifyUser(*sign_in_result.user); diff --git a/auth/tests/desktop/user_desktop_test.cc b/auth/tests/desktop/user_desktop_test.cc index bd466efe23..d4795cc19c 100644 --- a/auth/tests/desktop/user_desktop_test.cc +++ b/auth/tests/desktop/user_desktop_test.cc @@ -276,10 +276,10 @@ class UserDesktopTest : public ::testing::Test { id_token_listener.ExpectChanges(2); auth_state_listener.ExpectChanges(2); - Future future = firebase_auth_->SignInAnonymously(); + Future future = firebase_auth_->SignInAnonymously_DEPRECATED(); while (future.status() == kFutureStatusPending) { } - firebase_user_ = firebase_auth_->current_user(); + firebase_user_ = firebase_auth_->current_user_DEPRECATED(); EXPECT_NE(nullptr, firebase_user_); // Reset listeners before tests are run. @@ -343,8 +343,8 @@ class UserDesktopTest : public ::testing::Test { // Test that metadata is correctly being populated and exposed TEST_F(UserDesktopTest, TestAccountMetadata) { EXPECT_EQ(123, - firebase_auth_->current_user()->metadata().last_sign_in_timestamp); - EXPECT_EQ(456, firebase_auth_->current_user()->metadata().creation_timestamp); + firebase_auth_->current_user_DEPRECATED()->metadata().last_sign_in_timestamp); + EXPECT_EQ(456, firebase_auth_->current_user_DEPRECATED()->metadata().creation_timestamp); } TEST_F(UserDesktopTest, TestGetToken) { @@ -890,7 +890,7 @@ TEST_F(UserDesktopTest, TestRaceCondition_SetAccountInfoAndSignOut) { } EXPECT_THAT(future.error(), AnyOf(kAuthErrorNone, kAuthErrorNoSignedInUser)); - EXPECT_EQ(nullptr, firebase_auth_->current_user()); + EXPECT_EQ(nullptr, firebase_auth_->current_user_DEPRECATED()); } // LinkWithProvider tests. diff --git a/auth/tests/user_test.cc b/auth/tests/user_test.cc index c2e9176837..e9373b477c 100644 --- a/auth/tests/user_test.cc +++ b/auth/tests/user_test.cc @@ -167,9 +167,9 @@ class UserTest : public ::testing::Test { "}"); firebase_app_ = testing::CreateApp(); firebase_auth_ = Auth::GetAuth(firebase_app_); - Future result = firebase_auth_->SignInAnonymously(); + Future result = firebase_auth_->SignInAnonymously_DEPRECATED(); MaybeWaitForFuture(result); - firebase_user_ = firebase_auth_->current_user(); + firebase_user_ = firebase_auth_->current_user_DEPRECATED(); EXPECT_NE(nullptr, firebase_user_); } @@ -342,7 +342,7 @@ TEST_F(UserTest, TestReauthenticate) { Credential credential = EmailAuthProvider::GetCredential("i@email.com", "pw"); Future sign_in_result = - firebase_auth_->SignInWithCredential(credential); + firebase_auth_->SignInWithCredential_DEPRECATED(credential); Verify(sign_in_result); Future reauthenticate_result = diff --git a/database/integration_test/src/integration_test.cc b/database/integration_test/src/integration_test.cc index 211c0d3b5b..6d0af2101e 100644 --- a/database/integration_test/src/integration_test.cc +++ b/database/integration_test/src/integration_test.cc @@ -315,13 +315,13 @@ void FirebaseDatabaseTest::TerminateDatabase() { } void FirebaseDatabaseTest::SignIn() { - if (shared_auth_->current_user() != nullptr) { + if (shared_auth_->current_user_DEPRECATED() != nullptr) { // Already signed in. return; } LogDebug("Signing in."); firebase::Future sign_in_future = - shared_auth_->SignInAnonymously(); + shared_auth_->SignInAnonymously_DEPRECATED(); WaitForCompletion(sign_in_future, "SignInAnonymously"); if (sign_in_future.error() != 0) { FAIL() << "Ensure your application has the Anonymous sign-in provider " @@ -335,13 +335,13 @@ void FirebaseDatabaseTest::SignOut() { // Auth is not set up. return; } - if (shared_auth_->current_user() == nullptr) { + if (shared_auth_->current_user_DEPRECATED() == nullptr) { // Already signed out. return; } - if (shared_auth_->current_user()->is_anonymous()) { + if (shared_auth_->current_user_DEPRECATED()->is_anonymous()) { // If signed in anonymously, delete the anonymous user. - WaitForCompletion(shared_auth_->current_user()->Delete(), + WaitForCompletion(shared_auth_->current_user_DEPRECATED()->Delete(), "DeleteAnonymousUser"); } else { // If not signed in anonymously (e.g. if the tests were modified to sign in @@ -349,11 +349,11 @@ void FirebaseDatabaseTest::SignOut() { shared_auth_->SignOut(); // Wait for the sign-out to finish. - while (shared_auth_->current_user() != nullptr) { + while (shared_auth_->current_user_DEPRECATED() != nullptr) { if (ProcessEvents(100)) break; } } - EXPECT_EQ(shared_auth_->current_user(), nullptr); + EXPECT_EQ(shared_auth_->current_user_DEPRECATED(), nullptr); } firebase::database::DatabaseReference FirebaseDatabaseTest::CreateWorkingPath( @@ -371,7 +371,7 @@ TEST_F(FirebaseDatabaseTest, TestInitializeAndTerminate) { } TEST_F(FirebaseDatabaseTest, TestSignIn) { - EXPECT_NE(shared_auth_->current_user(), nullptr); + EXPECT_NE(shared_auth_->current_user_DEPRECATED(), nullptr); } TEST_F(FirebaseDatabaseTest, TestCreateWorkingPath) { diff --git a/firestore/integration_test/src/integration_test.cc b/firestore/integration_test/src/integration_test.cc index 6d63ba8c01..6e08b503e2 100644 --- a/firestore/integration_test/src/integration_test.cc +++ b/firestore/integration_test/src/integration_test.cc @@ -272,13 +272,13 @@ void FirebaseFirestoreBasicTest::TerminateFirestore() { } void FirebaseFirestoreBasicTest::SignIn() { - if (shared_auth_->current_user() != nullptr) { + if (shared_auth_->current_user_DEPRECATED() != nullptr) { // Already signed in. return; } LogDebug("Signing in."); firebase::Future sign_in_future = - shared_auth_->SignInAnonymously(); + shared_auth_->SignInAnonymously_DEPRECATED(); WaitForCompletion(sign_in_future, "SignInAnonymously"); if (sign_in_future.error() != 0) { FAIL() << "Ensure your application has the Anonymous sign-in provider " @@ -292,14 +292,14 @@ void FirebaseFirestoreBasicTest::SignOut() { // Auth is not set up. return; } - if (shared_auth_->current_user() == nullptr) { + if (shared_auth_->current_user_DEPRECATED() == nullptr) { // Already signed out. return; } - if (shared_auth_->current_user()->is_anonymous()) { + if (shared_auth_->current_user_DEPRECATED()->is_anonymous()) { // If signed in anonymously, delete the anonymous user. - WaitForCompletion(shared_auth_->current_user()->Delete(), + WaitForCompletion(shared_auth_->current_user_DEPRECATED()->Delete(), "DeleteAnonymousUser"); } else { // If not signed in anonymously (e.g. if the tests were modified to sign in @@ -307,11 +307,11 @@ void FirebaseFirestoreBasicTest::SignOut() { shared_auth_->SignOut(); // Wait for the sign-out to finish. - while (shared_auth_->current_user() != nullptr) { + while (shared_auth_->current_user_DEPRECATED() != nullptr) { if (ProcessEvents(100)) break; } } - EXPECT_EQ(shared_auth_->current_user(), nullptr); + EXPECT_EQ(shared_auth_->current_user_DEPRECATED(), nullptr); } firebase::firestore::CollectionReference @@ -345,7 +345,7 @@ TEST_F(FirebaseFirestoreBasicTest, TestInitializeAndTerminate) { } TEST_F(FirebaseFirestoreBasicTest, TestSignIn) { - EXPECT_NE(shared_auth_->current_user(), nullptr); + EXPECT_NE(shared_auth_->current_user_DEPRECATED(), nullptr); } TEST_F(FirebaseFirestoreBasicTest, TestAppAndSettings) { diff --git a/firestore/integration_test_internal/src/firestore_test.cc b/firestore/integration_test_internal/src/firestore_test.cc index 0569448f7d..ee6b6b44cb 100644 --- a/firestore/integration_test_internal/src/firestore_test.cc +++ b/firestore/integration_test_internal/src/firestore_test.cc @@ -1537,7 +1537,7 @@ TEST_F(FirestoreIntegrationTest, AuthWorks) { WriteDocument(doc, MapFieldValue{{"foo", FieldValue::Integer(42)}}); // Signing in should trigger an AuthStateListener event. - auto signin = auth->SignInAnonymously(); + auto signin = auth->SignInAnonymously_DEPRECATED(); Stopwatch stopwatch; Await(signin); stopwatch.stop(); diff --git a/firestore/integration_test_internal/src/integration_test.cc b/firestore/integration_test_internal/src/integration_test.cc index 13b36d59f6..c3889cdc68 100644 --- a/firestore/integration_test_internal/src/integration_test.cc +++ b/firestore/integration_test_internal/src/integration_test.cc @@ -275,13 +275,13 @@ void FirebaseFirestoreBasicTest::TerminateFirestore() { } void FirebaseFirestoreBasicTest::SignIn() { - if (shared_auth_->current_user() != nullptr) { + if (shared_auth_->current_user_DEPRECATED() != nullptr) { // Already signed in. return; } LogDebug("Signing in."); firebase::Future sign_in_future = - shared_auth_->SignInAnonymously(); + shared_auth_->SignInAnonymously_DEPRECATED(); WaitForCompletion(sign_in_future, "SignInAnonymously"); if (sign_in_future.error() != 0) { FAIL() << "Ensure your application has the Anonymous sign-in provider " @@ -295,14 +295,14 @@ void FirebaseFirestoreBasicTest::SignOut() { // Auth is not set up. return; } - if (shared_auth_->current_user() == nullptr) { + if (shared_auth_->current_user_DEPRECATED() == nullptr) { // Already signed out. return; } - if (shared_auth_->current_user()->is_anonymous()) { + if (shared_auth_->current_user_DEPRECATED()->is_anonymous()) { // If signed in anonymously, delete the anonymous user. - WaitForCompletion(shared_auth_->current_user()->Delete(), + WaitForCompletion(shared_auth_->current_user_DEPRECATED()->Delete(), "DeleteAnonymousUser"); } else { // If not signed in anonymously (e.g. if the tests were modified to sign in @@ -310,11 +310,11 @@ void FirebaseFirestoreBasicTest::SignOut() { shared_auth_->SignOut(); // Wait for the sign-out to finish. - while (shared_auth_->current_user() != nullptr) { + while (shared_auth_->current_user_DEPRECATED() != nullptr) { if (ProcessEvents(100)) break; } } - EXPECT_EQ(shared_auth_->current_user(), nullptr); + EXPECT_EQ(shared_auth_->current_user_DEPRECATED(), nullptr); } firebase::firestore::CollectionReference @@ -349,7 +349,7 @@ TEST_F(FirebaseFirestoreBasicTest, TestInitializeAndTerminate) { TEST_F(FirebaseFirestoreBasicTest, TestSignIn) { SKIP_TEST_ON_QUICK_CHECK; - EXPECT_NE(shared_auth_->current_user(), nullptr); + EXPECT_NE(shared_auth_->current_user_DEPRECATED(), nullptr); } TEST_F(FirebaseFirestoreBasicTest, TestAppAndSettings) { diff --git a/functions/integration_test/src/integration_test.cc b/functions/integration_test/src/integration_test.cc index 3759cfdcec..5f8ea23f1c 100644 --- a/functions/integration_test/src/integration_test.cc +++ b/functions/integration_test/src/integration_test.cc @@ -185,7 +185,7 @@ void FirebaseFunctionsTest::Terminate() { void FirebaseFunctionsTest::SignIn() { LogDebug("Signing in."); firebase::Future sign_in_future = - auth_->SignInAnonymously(); + auth_->SignInAnonymously_DEPRECATED(); WaitForCompletion(sign_in_future, "SignInAnonymously"); if (sign_in_future.error() != 0) { FAIL() << "Ensure your application has the Anonymous sign-in provider " @@ -252,7 +252,7 @@ TEST_F(FirebaseFunctionsTest, TestInitializeAndTerminate) { TEST_F(FirebaseFunctionsTest, TestSignIn) { SignIn(); - EXPECT_NE(auth_->current_user(), nullptr); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); } TEST_F(FirebaseFunctionsTest, TestFunction) { diff --git a/storage/integration_test/src/integration_test.cc b/storage/integration_test/src/integration_test.cc index 05632798c8..1921488e35 100644 --- a/storage/integration_test/src/integration_test.cc +++ b/storage/integration_test/src/integration_test.cc @@ -271,13 +271,13 @@ void FirebaseStorageTest::TerminateStorage() { } void FirebaseStorageTest::SignIn() { - if (shared_auth_->current_user() != nullptr) { + if (shared_auth_->current_user_DEPRECATED() != nullptr) { // Already signed in. return; } LogDebug("Signing in."); firebase::Future sign_in_future = - shared_auth_->SignInAnonymously(); + shared_auth_->SignInAnonymously_DEPRECATED(); WaitForCompletion(sign_in_future, "SignInAnonymously"); if (sign_in_future.error() != 0) { FAIL() << "Ensure your application has the Anonymous sign-in provider " @@ -291,13 +291,13 @@ void FirebaseStorageTest::SignOut() { // Auth is not set up. return; } - if (shared_auth_->current_user() == nullptr) { + if (shared_auth_->current_user_DEPRECATED() == nullptr) { // Already signed out. return; } - if (shared_auth_->current_user()->is_anonymous()) { + if (shared_auth_->current_user_DEPRECATED()->is_anonymous()) { // If signed in anonymously, delete the anonymous user. - WaitForCompletion(shared_auth_->current_user()->Delete(), + WaitForCompletion(shared_auth_->current_user_DEPRECATED()->Delete(), "DeleteAnonymousUser"); } else { // If not signed in anonymously (e.g. if the tests were modified to sign in @@ -305,11 +305,11 @@ void FirebaseStorageTest::SignOut() { shared_auth_->SignOut(); // Wait for the sign-out to finish. - while (shared_auth_->current_user() != nullptr) { + while (shared_auth_->current_user_DEPRECATED() != nullptr) { if (ProcessEvents(100)) break; } } - EXPECT_EQ(shared_auth_->current_user(), nullptr); + EXPECT_EQ(shared_auth_->current_user_DEPRECATED(), nullptr); } firebase::storage::StorageReference FirebaseStorageTest::CreateFolder() { @@ -330,7 +330,7 @@ TEST_F(FirebaseStorageTest, TestInitializeAndTerminate) { } TEST_F(FirebaseStorageTest, TestSignIn) { - EXPECT_NE(shared_auth_->current_user(), nullptr); + EXPECT_NE(shared_auth_->current_user_DEPRECATED(), nullptr); } TEST_F(FirebaseStorageTest, TestCreateWorkingFolder) { From 86cc5bd7c85e7b17319b917b7964b08be065c1af Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Fri, 10 Mar 2023 17:09:10 -0500 Subject: [PATCH 02/14] all three platforms build --- auth/integration_test/Info.plist | 8 +-- auth/integration_test/src/integration_test.cc | 26 ++++----- auth/samples/src/doc_samples.cc | 4 +- auth/src/android/auth_android.cc | 14 ++--- auth/src/android/credential_android.cc | 6 +-- auth/src/android/user_android.cc | 20 +++---- auth/src/auth.cc | 13 ++--- auth/src/common.h | 8 +++ auth/src/desktop/auth_desktop.cc | 14 ++--- .../auth_providers/federated_auth_provider.cc | 6 +-- auth/src/desktop/user_desktop.cc | 24 ++++----- auth/src/include/firebase/auth.h | 2 +- auth/src/include/firebase/auth/user.h | 53 ++++++++++++++----- auth/src/ios/auth_ios.mm | 12 ++--- auth/src/ios/credential_ios.mm | 6 +-- auth/src/ios/user_ios.mm | 20 +++---- auth/src/user.cc | 9 ++-- auth/tests/desktop/user_desktop_test.cc | 48 ++++++++--------- auth/tests/user_test.cc | 8 +-- 19 files changed, 168 insertions(+), 133 deletions(-) diff --git a/auth/integration_test/Info.plist b/auth/integration_test/Info.plist index 524550beb3..d7acd29687 100644 --- a/auth/integration_test/Info.plist +++ b/auth/integration_test/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) + com.google.FirebaseCppAuthTestApp.dev CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -22,10 +22,10 @@ CFBundleTypeRole Editor CFBundleURLName - $(PRODUCT_BUNDLE_IDENTIFIER) + com.google.FirebaseCppAuthTestApp.dev CFBundleURLSchemes - $(PRODUCT_BUNDLE_IDENTIFIER) + com.google.FirebaseCppAuthTestApp.dev @@ -35,7 +35,7 @@ google CFBundleURLSchemes - REPLACE_WITH_REVERSED_CLIENT_ID + com.googleusercontent.apps.53101460582-aosfj1hlbc89719t6qfian100u6hehh8 firebase-game-loop diff --git a/auth/integration_test/src/integration_test.cc b/auth/integration_test/src/integration_test.cc index f7faa0b5da..2cfdc82a3d 100644 --- a/auth/integration_test/src/integration_test.cc +++ b/auth/integration_test/src/integration_test.cc @@ -512,7 +512,7 @@ TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithEmailCredential) { kTestPassword); WaitForCompletion(user->LinkAndRetrieveDataWithCredential(credential), "LinkAndRetrieveDataWithCredential"); - WaitForCompletion(user->Unlink(credential.provider().c_str()), "Unlink"); + WaitForCompletion(user->Unlink_DEPRECATED(credential.provider().c_str()), "Unlink"); SignOut(); WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); @@ -520,16 +520,16 @@ TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithEmailCredential) { firebase::auth::Credential credential1 = firebase::auth::EmailAuthProvider::GetCredential(email1.c_str(), kTestPassword); - WaitForCompletion(user->LinkWithCredential(credential1), + WaitForCompletion(user->LinkWithCredential_DEPRECATED(credential1), "LinkWithCredential 1"); std::string email2 = GenerateEmailAddress(); firebase::auth::Credential credential2 = firebase::auth::EmailAuthProvider::GetCredential(email2.c_str(), kTestPassword); - WaitForCompletion(user->LinkWithCredential(credential2), + WaitForCompletion(user->LinkWithCredential_DEPRECATED(credential2), "LinkWithCredential 2", firebase::auth::kAuthErrorProviderAlreadyLinked); - WaitForCompletion(user->Unlink(credential.provider().c_str()), "Unlink 2"); + WaitForCompletion(user->Unlink_DEPRECATED(credential.provider().c_str()), "Unlink 2"); DeleteUser(); } @@ -540,7 +540,7 @@ TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithBadCredential) { firebase::auth::Credential twitter_cred = firebase::auth::TwitterAuthProvider::GetCredential(kTestIdTokenBad, kTestAccessTokenBad); - WaitForCompletion(pre_link_user->LinkWithCredential(twitter_cred), + WaitForCompletion(pre_link_user->LinkWithCredential_DEPRECATED(twitter_cred), "LinkWithCredential", firebase::auth::kAuthErrorInvalidCredential); // Ensure that user stays the same. @@ -1008,7 +1008,7 @@ TEST_F(FirebaseAuthTest, TestSuccessfulReauthenticateWithProvider) { auth_->SignInWithProvider_DEPRECATED(&provider); if (WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id)) { WaitForCompletion( - sign_in_future.result()->user->ReauthenticateWithProvider(&provider), + sign_in_future.result()->user->ReauthenticateWithProvider_DEPRECATED(&provider), "ReauthenticateWithProvider", provider_id); } DeleteUser(); @@ -1027,7 +1027,7 @@ TEST_F(FirebaseAuthTest, TestSuccessfulReauthenticateWithProviderNoScopes) { auth_->SignInWithProvider_DEPRECATED(&provider); if (WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id)) { WaitForCompletion( - sign_in_future.result()->user->ReauthenticateWithProvider(&provider), + sign_in_future.result()->user->ReauthenticateWithProvider_DEPRECATED(&provider), "ReauthenticateWithProvider", provider_id); } DeleteUser(); @@ -1047,7 +1047,7 @@ TEST_F(FirebaseAuthTest, auth_->SignInWithProvider_DEPRECATED(&provider); if (WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id)) { WaitForCompletion( - sign_in_future.result()->user->ReauthenticateWithProvider(&provider), + sign_in_future.result()->user->ReauthenticateWithProvider_DEPRECATED(&provider), "ReauthenticateWithProvider", provider_id); } DeleteUser(); @@ -1067,7 +1067,7 @@ TEST_F(FirebaseAuthTest, TestReauthenticateWithProviderBadProviderIdFails) { provider_data.provider_id = "MadeUpProvider"; firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future reauth_future = - auth_->current_user_DEPRECATED()->ReauthenticateWithProvider(&provider); + auth_->current_user_DEPRECATED()->ReauthenticateWithProvider_DEPRECATED(&provider); WaitForCompletion(reauth_future, "ReauthenticateWithProvider", firebase::auth::kAuthErrorInvalidProviderId); } @@ -1086,7 +1086,7 @@ TEST_F(FirebaseAuthTest, TestSuccessfulLinkFederatedProviderNoScopes) { provider_id, /*scopes=*/{}, /*custom_parameters=*/{{"req_id", "1234"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->current_user_DEPRECATED()->LinkWithProvider(&provider); + auth_->current_user_DEPRECATED()->LinkWithProvider_DEPRECATED(&provider); WaitForCompletion(sign_in_future, "LinkWithProvider", provider_id); DeleteUser(); } @@ -1104,7 +1104,7 @@ TEST_F(FirebaseAuthTest, provider_id, /*scopes=*/{}, /*custom_parameters=*/{}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->current_user_DEPRECATED()->LinkWithProvider(&provider); + auth_->current_user_DEPRECATED()->LinkWithProvider_DEPRECATED(&provider); WaitForCompletion(sign_in_future, "LinkWithProvider", provider_id); DeleteUser(); } @@ -1123,7 +1123,7 @@ TEST_F(FirebaseAuthTest, TestSuccessfulLinkFederatedProvider) { /*custom_parameters=*/{{"req_id", "1234"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->current_user_DEPRECATED()->LinkWithProvider(&provider); + auth_->current_user_DEPRECATED()->LinkWithProvider_DEPRECATED(&provider); WaitForCompletion(sign_in_future, "LinkWithProvider", provider_id); DeleteUser(); } @@ -1140,7 +1140,7 @@ TEST_F(FirebaseAuthTest, TestLinkFederatedProviderBadProviderIdFails) { /*custom_parameters=*/{{"req_id", "1234"}}); firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future sign_in_future = - auth_->current_user_DEPRECATED()->LinkWithProvider(&provider); + auth_->current_user_DEPRECATED()->LinkWithProvider_DEPRECATED(&provider); WaitForCompletion(sign_in_future, "LinkWithProvider", firebase::auth::kAuthErrorInvalidProviderId); DeleteUser(); diff --git a/auth/samples/src/doc_samples.cc b/auth/samples/src/doc_samples.cc index f9eae3045a..db80756f3d 100644 --- a/auth/samples/src/doc_samples.cc +++ b/auth/samples/src/doc_samples.cc @@ -532,7 +532,7 @@ void LinkCredential(const firebase::auth::Credential& credential, // Link the new credential to the currently active user. firebase::auth::User* current_user = auth->current_user_DEPRECATED(); firebase::Future result = - current_user->LinkWithCredential(credential); + current_user->LinkWithCredential_DEPRECATED(credential); // [END user_link] } @@ -541,7 +541,7 @@ void UnLinkCredential(const char* providerId, firebase::auth::Auth* auth) { // Unlink the sign-in provider from the currently active user. firebase::auth::User* current_user = auth->current_user_DEPRECATED(); firebase::Future result = - current_user->Unlink(providerId); + current_user->Unlink_DEPRECATED(providerId); // [END user_unlink] } diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index 44b2ed92a2..7888e52b90 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -395,7 +395,7 @@ Future Auth::FetchProvidersForEmail( Future Auth::SignInWithCustomToken_DEPRECATED(const char* token) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCustomToken); + const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED); JNIEnv* env = Env(auth_data_); jstring j_token = env->NewStringUTF(token); @@ -414,7 +414,7 @@ Future Auth::SignInWithCustomToken_DEPRECATED(const char* token) { Future Auth::SignInWithCredential_DEPRECATED(const Credential& credential) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential); + const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED); JNIEnv* env = Env(auth_data_); // If the credential itself is in an error state, don't try signing in. @@ -439,7 +439,7 @@ Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential& credential) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc( - kAuthFn_SignInAndRetrieveDataWithCredential); + kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED); JNIEnv* env = Env(auth_data_); // If the credential itself is in an error state, don't try signing in. @@ -466,7 +466,7 @@ Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider* Future Auth::SignInAnonymously_DEPRECATED() { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInAnonymously); + const auto handle = futures.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED); JNIEnv* env = Env(auth_data_); jobject pending_result = env->CallObjectMethod( @@ -485,7 +485,7 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char* email, const char* password) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = - futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword); + futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED); if (!email || strlen(email) == 0 || !password || strlen(password) == 0) { futures.Complete(handle, @@ -518,7 +518,7 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char* email, const char* password) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = - futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword); + futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED); if (!email || strlen(email) == 0 || !password || strlen(password) == 0) { futures.Complete(handle, @@ -533,7 +533,7 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char* email, jstring j_password = env->NewStringUTF(password); jobject pending_result = env->CallObjectMethod( AuthImpl(auth_data_), - auth::GetMethodId(auth::kCreateUserWithEmailAndPassword), j_email, + auth::GetMethodId(auth::kCreateUserWithEmailAndPassword_DEPRECATED), j_email, j_password); env->DeleteLocalRef(j_email); env->DeleteLocalRef(j_password); diff --git a/auth/src/android/credential_android.cc b/auth/src/android/credential_android.cc index 192934298f..930f8bae48 100644 --- a/auth/src/android/credential_android.cc +++ b/auth/src/android/credential_android.cc @@ -1015,7 +1015,7 @@ Future FederatedOAuthProvider::SignIn(AuthData* auth_data) { ReferenceCountedFutureImpl& futures = auth_data->future_impl; const auto handle = futures.SafeAlloc( - kAuthFn_SignInWithProvider, SignInResult()); + kAuthFn_SignInWithProvider_DEPRECATED, SignInResult()); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { @@ -1039,7 +1039,7 @@ Future FederatedOAuthProvider::Link(AuthData* auth_data) { JNIEnv* env = Env(auth_data); ReferenceCountedFutureImpl& futures = auth_data->future_impl; const auto handle = - futures.SafeAlloc(kUserFn_LinkWithProvider, SignInResult()); + futures.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { @@ -1064,7 +1064,7 @@ Future FederatedOAuthProvider::Reauthenticate( JNIEnv* env = Env(auth_data); ReferenceCountedFutureImpl& futures = auth_data->future_impl; const auto handle = futures.SafeAlloc( - kUserFn_ReauthenticateWithProvider, SignInResult()); + kUserFn_ReauthenticateWithProvider_DEPRECATED, SignInResult()); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { diff --git a/auth/src/android/user_android.cc b/auth/src/android/user_android.cc index a9769f057e..ab4efcee39 100644 --- a/auth/src/android/user_android.cc +++ b/auth/src/android/user_android.cc @@ -466,12 +466,12 @@ Future User::UpdateUserProfile(const UserProfile& profile) { return MakeFuture(&futures, handle); } -Future User::LinkWithCredential(const Credential& credential) { +Future User::LinkWithCredential_DEPRECATED(const Credential& credential) { if (!ValidUser(auth_data_)) { return Future(); } ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_LinkWithCredential); + const auto handle = futures.SafeAlloc(kUserFn_LinkWithCredential_DEPRECATED); JNIEnv* env = Env(auth_data_); jobject pending_result = env->CallObjectMethod( @@ -507,18 +507,18 @@ Future User::LinkAndRetrieveDataWithCredential( return MakeFuture(&futures, handle); } -Future User::LinkWithProvider( +Future User::LinkWithProvider_DEPRECATED( FederatedAuthProvider* provider) const { FIREBASE_ASSERT_RETURN(Future(), provider); return provider->Link(auth_data_); } -Future User::Unlink(const char* provider) { +Future User::Unlink_DEPRECATED(const char* provider) { if (!ValidUser(auth_data_)) { return Future(); } ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Unlink); + const auto handle = futures.SafeAlloc(kUserFn_Unlink_DEPRECATED); JNIEnv* env = Env(auth_data_); jstring j_provider = env->NewStringUTF(provider); @@ -534,13 +534,13 @@ Future User::Unlink(const char* provider) { return MakeFuture(&futures, handle); } -Future User::UpdatePhoneNumberCredential(const Credential& credential) { +Future User::UpdatePhoneNumberCredential_DEPRECATED(const Credential& credential) { if (!ValidUser(auth_data_)) { return Future(); } ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = - futures.SafeAlloc(kUserFn_UpdatePhoneNumberCredential); + futures.SafeAlloc(kUserFn_UpdatePhoneNumberCredential_DEPRECATED); JNIEnv* env = Env(auth_data_); jobject j_credential = CredentialFromImpl(credential.impl_); @@ -598,14 +598,14 @@ Future User::Reauthenticate(const Credential& credential) { return MakeFuture(&futures, handle); } -Future User::ReauthenticateAndRetrieveData( +Future User::ReauthenticateAndRetrieveData_DEPRECATED( const Credential& credential) { if (!ValidUser(auth_data_)) { return Future(); } ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = - futures.SafeAlloc(kUserFn_ReauthenticateAndRetrieveData); + futures.SafeAlloc(kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); JNIEnv* env = Env(auth_data_); jobject pending_result = env->CallObjectMethod( @@ -620,7 +620,7 @@ Future User::ReauthenticateAndRetrieveData( return MakeFuture(&futures, handle); } -Future User::ReauthenticateWithProvider( +Future User::ReauthenticateWithProvider_DEPRECATED( FederatedAuthProvider* provider) const { FIREBASE_ASSERT_RETURN(Future(), provider); return provider->Reauthenticate(auth_data_); diff --git a/auth/src/auth.cc b/auth/src/auth.cc index 1edce34faf..8760439dd5 100644 --- a/auth/src/auth.cc +++ b/auth/src/auth.cc @@ -364,13 +364,14 @@ AUTH_NOTIFY_LISTENERS(NotifyIdTokenListeners, "ID token", id_token_listeners, OnIdTokenChanged); AUTH_RESULT_FN(Auth, FetchProvidersForEmail, Auth::FetchProvidersResult) -AUTH_RESULT_FN(Auth, SignInWithCustomToken_DEPRECATED, User*) -AUTH_RESULT_FN(Auth, SignInWithCredential_DEPRECATED, User*) -AUTH_RESULT_FN(Auth, SignInAndRetrieveDataWithCredential_DEPRECATED, SignInResult) -AUTH_RESULT_FN(Auth, SignInAnonymously_DEPRECATED, User*) -AUTH_RESULT_FN(Auth, SignInWithEmailAndPassword_DEPRECATED, User*) -AUTH_RESULT_FN(Auth, CreateUserWithEmailAndPassword_DEPRECATED, User*) AUTH_RESULT_FN(Auth, SendPasswordResetEmail, void) +AUTH_RESULT_DEPRECATED_FN(Auth, SignInWithCustomToken, User*) +AUTH_RESULT_DEPRECATED_FN(Auth, SignInWithCredential, User*) +AUTH_RESULT_DEPRECATED_FN(Auth, SignInAndRetrieveDataWithCredential, SignInResult) +AUTH_RESULT_DEPRECATED_FN(Auth, SignInAnonymously, User*) +AUTH_RESULT_DEPRECATED_FN(Auth, SignInWithEmailAndPassword, User*) +AUTH_RESULT_DEPRECATED_FN(Auth, CreateUserWithEmailAndPassword, User*) + } // namespace auth } // namespace firebase diff --git a/auth/src/common.h b/auth/src/common.h index f92acb301f..8e09dd08fb 100644 --- a/auth/src/common.h +++ b/auth/src/common.h @@ -51,6 +51,14 @@ void LogHeartbeat(Auth* auth); auth_data_->future_impl.LastResult(k##class_name##Fn_##fn_name)); \ } +// All the result functions are similar. +// Just return the local Future, cast to the proper result type. +#define AUTH_RESULT_DEPRECATED_FN(class_name, fn_name, result_type) \ + Future class_name::fn_name##LastResult_DEPRECATED() const { \ + return static_cast&>( \ + auth_data_->future_impl.LastResult(k##class_name##Fn_##fn_name##_DEPRECATED)); \ + } + // Returns true if `auth_data` has a user that's currently active. inline bool ValidUser(const AuthData* auth_data) { return auth_data->user_impl != nullptr; diff --git a/auth/src/desktop/auth_desktop.cc b/auth/src/desktop/auth_desktop.cc index bcbd13bd3d..80d03e4549 100644 --- a/auth/src/desktop/auth_desktop.cc +++ b/auth/src/desktop/auth_desktop.cc @@ -339,7 +339,7 @@ void Auth::DestroyPlatformAuth(AuthData* const auth_data) { Future Auth::SignInWithCustomToken_DEPRECATED(const char* const custom_token) { Promise promise(&auth_data_->future_impl, - kAuthFn_SignInWithCustomToken); + kAuthFn_SignInWithCustomToken_DEPRECATED); if (!custom_token || strlen(custom_token) == 0) { FailPromise(&promise, kAuthErrorInvalidCustomToken); return promise.LastResult(); @@ -357,7 +357,7 @@ Future Auth::SignInWithCustomToken_DEPRECATED(const char* const custom_to Future Auth::SignInWithCredential_DEPRECATED(const Credential& credential) { Promise promise(&auth_data_->future_impl, - kAuthFn_SignInWithCredential); + kAuthFn_SignInWithCredential_DEPRECATED); if (!ValidateCredential(&promise, credential.provider(), credential.impl_)) { return promise.LastResult(); } @@ -373,7 +373,7 @@ Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider* SafeFutureHandle handle = auth_data_->future_impl.SafeAlloc( - kAuthFn_SignInWithProvider); + kAuthFn_SignInWithProvider_DEPRECATED); auth_data_->future_impl.CompleteWithResult( handle, kAuthErrorUnimplemented, "Operation is not supported on non-mobile systems.", @@ -382,7 +382,7 @@ Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider* } Future Auth::SignInAnonymously_DEPRECATED() { - Promise promise(&auth_data_->future_impl, kAuthFn_SignInAnonymously); + Promise promise(&auth_data_->future_impl, kAuthFn_SignInAnonymously_DEPRECATED); // If user is already signed in anonymously, return immediately. bool is_anonymous = false; @@ -408,7 +408,7 @@ Future Auth::SignInAnonymously_DEPRECATED() { Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char* const email, const char* const password) { Promise promise(&auth_data_->future_impl, - kAuthFn_SignInWithEmailAndPassword); + kAuthFn_SignInWithEmailAndPassword_DEPRECATED); if (!ValidateEmailAndPassword(&promise, email, password)) { return promise.LastResult(); } @@ -424,7 +424,7 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char* const emai Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char* const email, const char* const password) { Promise promise(&auth_data_->future_impl, - kAuthFn_CreateUserWithEmailAndPassword); + kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED); if (!ValidateEmailAndPassword(&promise, email, password)) { return promise.LastResult(); } @@ -441,7 +441,7 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char* const Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential& credential) { Promise promise(&auth_data_->future_impl, - kAuthFn_SignInAndRetrieveDataWithCredential); + kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED); return DoSignInWithCredential(promise, auth_data_, credential.provider(), credential.impl_); } diff --git a/auth/src/desktop/auth_providers/federated_auth_provider.cc b/auth/src/desktop/auth_providers/federated_auth_provider.cc index 7d6a30c71d..94087abeb4 100644 --- a/auth/src/desktop/auth_providers/federated_auth_provider.cc +++ b/auth/src/desktop/auth_providers/federated_auth_provider.cc @@ -81,7 +81,7 @@ Future FederatedOAuthProvider::SignIn(AuthData* auth_data) { FIREBASE_ASSERT_RETURN(Future(), handler_); assert(auth_data); Future future = - CreateAuthFuture(auth_data, kAuthFn_SignInWithProvider); + CreateAuthFuture(auth_data, kAuthFn_SignInWithProvider_DEPRECATED); if (future.status() == kFutureStatusPending) { AuthCompletionHandle* auth_completion_handle = new AuthCompletionHandle( SafeFutureHandle(future.GetHandle()), auth_data); @@ -94,7 +94,7 @@ Future FederatedOAuthProvider::Link(AuthData* auth_data) { assert(auth_data); FIREBASE_ASSERT_RETURN(Future(), handler_); Future future = - CreateAuthFuture(auth_data, kUserFn_LinkWithProvider); + CreateAuthFuture(auth_data, kUserFn_LinkWithProvider_DEPRECATED); if (future.status() == kFutureStatusPending) { AuthCompletionHandle* auth_completion_handle = new AuthCompletionHandle( SafeFutureHandle(future.GetHandle()), auth_data); @@ -108,7 +108,7 @@ Future FederatedOAuthProvider::Reauthenticate( assert(auth_data); FIREBASE_ASSERT_RETURN(Future(), handler_); Future future = - CreateAuthFuture(auth_data, kUserFn_ReauthenticateWithProvider); + CreateAuthFuture(auth_data, kUserFn_ReauthenticateWithProvider_DEPRECATED); if (future.status() == kFutureStatusPending) { AuthCompletionHandle* auth_completion_handle = new AuthCompletionHandle( SafeFutureHandle(future.GetHandle()), auth_data); diff --git a/auth/src/desktop/user_desktop.cc b/auth/src/desktop/user_desktop.cc index f066b0c097..0f5a100598 100644 --- a/auth/src/desktop/user_desktop.cc +++ b/auth/src/desktop/user_desktop.cc @@ -811,8 +811,8 @@ Future User::UpdateUserProfile(const UserProfile& profile) { PerformSetAccountInfoFlow); } -Future User::Unlink(const char* const provider) { - Promise promise(&auth_data_->future_impl, kUserFn_Unlink); +Future User::Unlink_DEPRECATED(const char* const provider) { + Promise promise(&auth_data_->future_impl, kUserFn_Unlink_DEPRECATED); if (!provider || strlen(provider) == 0) { FailPromise(&promise, kAuthErrorNoSuchProvider); return promise.LastResult(); @@ -840,8 +840,8 @@ Future User::Unlink(const char* const provider) { PerformSetAccountInfoFlow); } -Future User::LinkWithCredential(const Credential& credential) { - Promise promise(&auth_data_->future_impl, kUserFn_LinkWithCredential); +Future User::LinkWithCredential_DEPRECATED(const Credential& credential) { + Promise promise(&auth_data_->future_impl, kUserFn_LinkWithCredential_DEPRECATED); return DoLinkCredential(promise, auth_data_, credential.provider(), credential.impl_); } @@ -854,13 +854,13 @@ Future User::LinkAndRetrieveDataWithCredential( credential.impl_); } -Future User::LinkWithProvider( +Future User::LinkWithProvider_DEPRECATED( FederatedAuthProvider* provider) const { FIREBASE_ASSERT_RETURN(Future(), provider); // TODO(b/139363200) // return provider->Link(auth_data_); SafeFutureHandle handle = - auth_data_->future_impl.SafeAlloc(kUserFn_LinkWithProvider); + auth_data_->future_impl.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED); auth_data_->future_impl.CompleteWithResult( handle, kAuthErrorUnimplemented, "Operation is not supported on non-mobile systems.", @@ -874,22 +874,22 @@ Future User::Reauthenticate(const Credential& credential) { credential.impl_); } -Future User::ReauthenticateAndRetrieveData( +Future User::ReauthenticateAndRetrieveData_DEPRECATED( const Credential& credential) { Promise promise(&auth_data_->future_impl, - kUserFn_ReauthenticateAndRetrieveData); + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); return DoReauthenticate(promise, auth_data_, credential.provider(), credential.impl_); } -Future User::ReauthenticateWithProvider( +Future User::ReauthenticateWithProvider_DEPRECATED( FederatedAuthProvider* provider) const { FIREBASE_ASSERT_RETURN(Future(), provider); // TODO(b/139363200) // return provider->Reauthenticate(auth_data_); SafeFutureHandle handle = auth_data_->future_impl.SafeAlloc( - kUserFn_ReauthenticateWithProvider); + kUserFn_ReauthenticateWithProvider_DEPRECATED); auth_data_->future_impl.CompleteWithResult( handle, kAuthErrorUnimplemented, "Operation is not supported on non-mobile systems.", @@ -954,9 +954,9 @@ std::string User::provider_id() const { // Not implemented -Future User::UpdatePhoneNumberCredential(const Credential& credential) { +Future User::UpdatePhoneNumberCredential_DEPRECATED(const Credential& credential) { Promise promise(&auth_data_->future_impl, - kUserFn_UpdatePhoneNumberCredential); + kUserFn_UpdatePhoneNumberCredential_DEPRECATED); if (!ValidateCurrentUser(&promise, auth_data_)) { return promise.LastResult(); } diff --git a/auth/src/include/firebase/auth.h b/auth/src/include/firebase/auth.h index 015a12197f..2733aa3aa9 100644 --- a/auth/src/include/firebase/auth.h +++ b/auth/src/include/firebase/auth.h @@ -277,7 +277,7 @@ class Auth { /// @note: This operation is supported only on iOS, tvOS and Android /// platforms. On other platforms this method will return a Future with a /// preset error code: kAuthErrorUnimplemented. - FIREBASE_DEPRECATED Future SignInWithProvider_DEPRCATED(FederatedAuthProvider* provider); + FIREBASE_DEPRECATED Future SignInWithProvider_DEPRECATED(FederatedAuthProvider* provider); /// @deprecated This is a deprecated method. Please use @SignInAndRetrieveDataWithCredential instead. /// diff --git a/auth/src/include/firebase/auth/user.h b/auth/src/include/firebase/auth/user.h index ddd1ba8906..44949a4c20 100644 --- a/auth/src/include/firebase/auth/user.h +++ b/auth/src/include/firebase/auth/user.h @@ -253,6 +253,9 @@ class User : public UserInfoInterface { /// Get results of the most recent call to @ref Reauthenticate. Future ReauthenticateLastResult() const; + /// @deprecated This is a deprecated method. Please use + /// @ref ReauthenticateAndRetrieveData(const Credential&) instead. + /// /// Reauthenticate using a credential. /// /// @if cpp_examples @@ -279,12 +282,17 @@ class User : public UserInfoInterface { /// or if sign-in with that credential failed. /// @note: The current user may be signed out if this operation fails on /// Android and desktop platforms. - Future ReauthenticateAndRetrieveData( + FIREBASE_DEPRECATED Future ReauthenticateAndRetrieveData_DEPRECATED( const Credential& credential); + /// @deprecated + /// /// Get results of the most recent call to @ref ReauthenticateAndRetrieveData. - Future ReauthenticateAndRetrieveDataLastResult() const; + FIREBASE_DEPRECATED Future ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const; + /// @deprecated This is a deprecated method. Please use + /// @ref ReauthenticateWithProvider(FederatedAuthProvider*) instead. + /// /// @brief Re-authenticates the user with a federated auth provider. /// /// @param[in] provider Contains information on the auth provider to @@ -294,7 +302,7 @@ class User : public UserInfoInterface { /// @note: This operation is supported only on iOS, tvOS and Android /// platforms. On other platforms this method will return a Future with a /// preset error code: kAuthErrorUnimplemented. - Future ReauthenticateWithProvider( + Future ReauthenticateWithProvider_DEPRECATED( FederatedAuthProvider* provider) const; /// Initiates email verification for the user. @@ -309,12 +317,17 @@ class User : public UserInfoInterface { /// Get results of the most recent call to @ref UpdateUserProfile. Future UpdateUserProfileLastResult() const; + /// @deprecated This is a deprecated method. Please use + /// @ref LinkWithCredential(const Credential&) instead. + /// /// Convenience function for @ref ReauthenticateAndRetrieveData that discards /// the returned @ref AdditionalUserInfo in @ref SignInResult. - Future LinkWithCredential(const Credential& credential); + FIREBASE_DEPRECATED Future LinkWithCredential_DEPRECATED(const Credential& credential); - /// Get results of the most recent call to @ref LinkWithCredential. - Future LinkWithCredentialLastResult() const; + /// @deprecated + /// + /// Get results of the most recent call to @ref LinkWithCredential_DEPRECATED. + FIREBASE_DEPRECATED Future LinkWithCredentialLastResult_DEPRECATED() const; /// Links the user with the given 3rd party credentials. /// @@ -334,6 +347,9 @@ class User : public UserInfoInterface { /// @ref LinkAndRetrieveDataWithCredential. Future LinkAndRetrieveDataWithCredentialLastResult() const; + /// @deprecated This is a deprecated method. Please use + /// @ref LinkWithProvider(FederatedAuthProvider*) instead. + /// /// Links this user with a federated auth provider. /// /// @param[in] provider Contains information on the auth provider to link @@ -344,24 +360,33 @@ class User : public UserInfoInterface { /// @note: This operation is supported only on iOS, tvOS and Android /// platforms. On other platforms this method will return a Future with a /// preset error code: kAuthErrorUnimplemented. - Future LinkWithProvider(FederatedAuthProvider* provider) const; + Future LinkWithProvider_DEPRECATED(FederatedAuthProvider* provider) const; + /// @deprecated This is a deprecated method. Please use @ref Unlink(const char*) instead. + /// /// Unlinks the current user from the provider specified. /// Status will be an error if the user is not linked to the given provider. - Future Unlink(const char* provider); + Future Unlink_DEPRECATED(const char* provider); + /// @deprecated + /// /// Get results of the most recent call to @ref Unlink. - Future UnlinkLastResult() const; + Future UnlinkLastResult_DEPRECATED() const; + /// @deprecated This is a deprecated method. Please use + /// @ref UpdatePhoneNumberCredential(const PhoneAuthCredential&) instead. + /// /// Updates the currently linked phone number on the user. /// This is useful when a user wants to change their phone number. It is a - /// shortcut to calling Unlink(phone_credential.provider().c_str()) and then - /// LinkWithCredential(phone_credential). + /// shortcut to calling Unlink_DEPRECATED(phone_credential.provider().c_str()) and then + /// LinkWithCredential_DEPRECATED(phone_credential). /// `credential` must have been created with @ref PhoneAuthProvider. - Future UpdatePhoneNumberCredential(const Credential& credential); + Future UpdatePhoneNumberCredential_DEPRECATED(const Credential& credential); - /// Get results of the most recent call to @ref UpdatePhoneNumberCredential. - Future UpdatePhoneNumberCredentialLastResult() const; + /// @deprecated + //// + /// Get results of the most recent call to @ref UpdatePhoneNumberCredential_DEPRECATED. + Future UpdatePhoneNumberCredentialLastResult_DEPRECATED() const; /// Refreshes the data for this user. /// diff --git a/auth/src/ios/auth_ios.mm b/auth/src/ios/auth_ios.mm index d3fce962d2..8a7bacd289 100644 --- a/auth/src/ios/auth_ios.mm +++ b/auth/src/ios/auth_ios.mm @@ -362,7 +362,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SignInWithCustomToken_DEPRECATED(const char *token) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCustomToken, nullptr); + const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED, nullptr); [AuthImpl(auth_data_) signInWithCustomToken:@(token) @@ -375,7 +375,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SignInWithCredential_DEPRECATED(const Credential &credential) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential, nullptr); + const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED, nullptr); [AuthImpl(auth_data_) signInWithCredential:CredentialFromImpl(credential.impl_) @@ -389,7 +389,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED(const Credential &credential) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = - futures.SafeAlloc(kAuthFn_SignInAndRetrieveDataWithCredential, SignInResult()); + futures.SafeAlloc(kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED, SignInResult()); [AuthImpl(auth_data_) signInWithCredential:CredentialFromImpl(credential.impl_) @@ -407,7 +407,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SignInAnonymously_DEPRECATED() { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = auth_data_->future_impl.SafeAlloc(kAuthFn_SignInAnonymously, nullptr); + const auto handle = auth_data_->future_impl.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED, nullptr); [AuthImpl(auth_data_) signInAnonymouslyWithCompletion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { @@ -419,7 +419,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword, nullptr); + const auto handle = futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED, nullptr); if (!email || strlen(email) == 0) { futures.Complete(handle, kAuthErrorMissingEmail, "Empty email is not allowed."); } else if (!password || strlen(password) == 0) { @@ -437,7 +437,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword, nullptr); + const auto handle = futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED, nullptr); if (!email || strlen(email) == 0) { futures.Complete(handle, kAuthErrorMissingEmail, "Empty email is not allowed."); } else if (!password || strlen(password) == 0) { diff --git a/auth/src/ios/credential_ios.mm b/auth/src/ios/credential_ios.mm index 5c271f907c..86d1d860c0 100644 --- a/auth/src/ios/credential_ios.mm +++ b/auth/src/ios/credential_ios.mm @@ -454,7 +454,7 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl Future FederatedOAuthProvider::SignIn(AuthData* auth_data) { assert(auth_data); ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithProvider, SignInResult()); + const auto handle = futures.SafeAlloc(kAuthFn_SignInWithProvider_DEPRECATED, SignInResult()); FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) auth:AuthImpl(auth_data)]; @@ -480,7 +480,7 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl Future FederatedOAuthProvider::Link(AuthData* auth_data) { assert(auth_data); ReferenceCountedFutureImpl& futures = auth_data->future_impl; - auto handle = futures.SafeAlloc(kUserFn_LinkWithProvider, SignInResult()); + auto handle = futures.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) @@ -514,7 +514,7 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl Future FederatedOAuthProvider::Reauthenticate(AuthData* auth_data) { assert(auth_data); ReferenceCountedFutureImpl& futures = auth_data->future_impl; - auto handle = futures.SafeAlloc(kUserFn_LinkWithProvider, SignInResult()); + auto handle = futures.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) diff --git a/auth/src/ios/user_ios.mm b/auth/src/ios/user_ios.mm index e4c3817440..c34b987683 100644 --- a/auth/src/ios/user_ios.mm +++ b/auth/src/ios/user_ios.mm @@ -160,12 +160,12 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { return MakeFuture(&futures, handle); } -Future User::LinkWithCredential(const Credential &credential) { +Future User::LinkWithCredential_DEPRECATED(const Credential &credential) { if (!ValidUser(auth_data_)) { return Future(); } ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_LinkWithCredential); + const auto handle = futures.SafeAlloc(kUserFn_LinkWithCredential_DEPRECATED); [UserImpl(auth_data_) linkWithCredential:CredentialFromImpl(credential.impl_) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { @@ -189,17 +189,17 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { return MakeFuture(&futures, handle); } -Future User::LinkWithProvider(FederatedAuthProvider *provider) const { +Future User::LinkWithProvider_DEPRECATED(FederatedAuthProvider *provider) const { FIREBASE_ASSERT_RETURN(Future(), provider); return provider->Link(auth_data_); } -Future User::Unlink(const char *provider) { +Future User::Unlink_DEPRECATED(const char *provider) { if (!ValidUser(auth_data_)) { return Future(); } ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Unlink); + const auto handle = futures.SafeAlloc(kUserFn_Unlink_DEPRECATED); [UserImpl(auth_data_) unlinkFromProvider:@(provider) completion:^(FIRUser *_Nullable user, NSError *_Nullable error) { SignInCallback(user, error, handle, auth_data_); @@ -207,12 +207,12 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { return MakeFuture(&futures, handle); } -Future User::UpdatePhoneNumberCredential(const Credential &credential) { +Future User::UpdatePhoneNumberCredential_DEPRECATED(const Credential &credential) { if (!ValidUser(auth_data_)) { return Future(); } ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdatePhoneNumberCredential); + const auto handle = futures.SafeAlloc(kUserFn_UpdatePhoneNumberCredential_DEPRECATED); #if FIREBASE_PLATFORM_IOS FIRAuthCredential *objc_credential = CredentialFromImpl(credential.impl_); @@ -265,13 +265,13 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { return MakeFuture(&futures, handle); } -Future User::ReauthenticateAndRetrieveData(const Credential &credential) { +Future User::ReauthenticateAndRetrieveData_DEPRECATED(const Credential &credential) { if (!ValidUser(auth_data_)) { return Future(); } ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = auth_data_->future_impl.SafeAlloc( - kUserFn_ReauthenticateAndRetrieveData, SignInResult()); + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED, SignInResult()); [UserImpl(auth_data_) reauthenticateWithCredential:CredentialFromImpl(credential.impl_) @@ -282,7 +282,7 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { return MakeFuture(&futures, handle); } -Future User::ReauthenticateWithProvider(FederatedAuthProvider *provider) const { +Future User::ReauthenticateWithProvider_DEPRECATED(FederatedAuthProvider *provider) const { FIREBASE_ASSERT_RETURN(Future(), provider); return provider->Reauthenticate(auth_data_); } diff --git a/auth/src/user.cc b/auth/src/user.cc index ea9f5e2399..52693c0b6a 100644 --- a/auth/src/user.cc +++ b/auth/src/user.cc @@ -23,16 +23,17 @@ AUTH_RESULT_FN(User, GetToken, std::string) AUTH_RESULT_FN(User, UpdateEmail, void) AUTH_RESULT_FN(User, UpdatePassword, void) AUTH_RESULT_FN(User, Reauthenticate, void) -AUTH_RESULT_FN(User, ReauthenticateAndRetrieveData, SignInResult) AUTH_RESULT_FN(User, SendEmailVerification, void) AUTH_RESULT_FN(User, UpdateUserProfile, void) -AUTH_RESULT_FN(User, LinkWithCredential, User*) AUTH_RESULT_FN(User, LinkAndRetrieveDataWithCredential, SignInResult) -AUTH_RESULT_FN(User, Unlink, User*) -AUTH_RESULT_FN(User, UpdatePhoneNumberCredential, User*) AUTH_RESULT_FN(User, Reload, void) AUTH_RESULT_FN(User, Delete, void) +AUTH_RESULT_DEPRECATED_FN(User, ReauthenticateAndRetrieveData, SignInResult) +AUTH_RESULT_DEPRECATED_FN(User, LinkWithCredential, User*) +AUTH_RESULT_DEPRECATED_FN(User, Unlink, User*) +AUTH_RESULT_DEPRECATED_FN(User, UpdatePhoneNumberCredential, User*) + #if defined(INTERNAL_EXPERIMENTAL) // I'd like to change all the above functions to use LastResultProxy, as it // makes multi-threaded situations more deterministic. However, LastResult diff --git a/auth/tests/desktop/user_desktop_test.cc b/auth/tests/desktop/user_desktop_test.cc index d4795cc19c..1dcba4cee8 100644 --- a/auth/tests/desktop/user_desktop_test.cc +++ b/auth/tests/desktop/user_desktop_test.cc @@ -311,7 +311,7 @@ class UserDesktopTest : public ::testing::Test { FederatedOAuthProvider* provider, OAuthProviderTestHandler* handler, bool trigger_link) { InitializeSuccessfulAuthenticateWithProviderFlow(provider, handler); - Future future = firebase_user_->LinkWithProvider(provider); + Future future = firebase_user_->LinkWithProvider_DEPRECATED(provider); if (trigger_link) { handler->TriggerLinkComplete(); } @@ -323,7 +323,7 @@ class UserDesktopTest : public ::testing::Test { bool trigger_reauthenticate) { InitializeSuccessfulAuthenticateWithProviderFlow(provider, handler); Future future = - firebase_user_->ReauthenticateWithProvider(provider); + firebase_user_->ReauthenticateWithProvider_DEPRECATED(provider); if (trigger_reauthenticate) { handler->TriggerReauthenticateComplete(); } @@ -531,7 +531,7 @@ TEST_F(UserDesktopTest, TestUnlink) { auth_state_listener.ExpectChanges(0); WaitForFuture(firebase_user_->Reload()); - WaitForFuture(firebase_user_->Unlink("fake_provider_id")); + WaitForFuture(firebase_user_->Unlink_DEPRECATED("fake_provider_id")); VerifyProviderData(*firebase_user_); } @@ -542,7 +542,7 @@ TEST_F(UserDesktopTest, TestUnlink_NonLinkedProvider) { id_token_listener.ExpectChanges(0); auth_state_listener.ExpectChanges(0); - WaitForFuture(firebase_user_->Unlink("no_such_provider"), + WaitForFuture(firebase_user_->Unlink_DEPRECATED("no_such_provider"), kAuthErrorNoSuchProvider); } @@ -557,7 +557,7 @@ TEST_F(UserDesktopTest, TestLinkWithCredential_OauthCredential) { const Credential credential = GoogleAuthProvider::GetCredential("fake_id_token", ""); const User* const user = - WaitForFuture(firebase_user_->LinkWithCredential(credential)); + WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(credential)); EXPECT_FALSE(user->is_anonymous()); VerifyUser(*user); } @@ -577,7 +577,7 @@ TEST_F(UserDesktopTest, TestLinkWithCredential_EmailCredential) { EXPECT_TRUE(firebase_user_->is_anonymous()); const Credential credential = EmailAuthProvider::GetCredential(new_email.c_str(), "fake_password"); - WaitForFuture(firebase_user_->LinkWithCredential(credential)); + WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(credential)); EXPECT_EQ(new_email, firebase_user_->email()); EXPECT_FALSE(firebase_user_->is_anonymous()); } @@ -594,7 +594,7 @@ TEST_F(UserDesktopTest, TestLinkWithCredential_NeedsConfirmation) { const Credential credential = GoogleAuthProvider::GetCredential("fake_id_token", ""); - WaitForFuture(firebase_user_->LinkWithCredential(credential), + WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(credential), kAuthErrorAccountExistsWithDifferentCredentials); } @@ -624,10 +624,10 @@ TEST_F(UserDesktopTest, TestLinkWithCredential_ChecksAlreadyLinkedProviders) { const Credential google_credential = GoogleAuthProvider::GetCredential("fake_id_token", ""); - WaitForFuture(firebase_user_->LinkWithCredential(google_credential)); + WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(google_credential)); // The same provider shouldn't be linked twice. - WaitForFuture(firebase_user_->LinkWithCredential(google_credential), + WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(google_credential), kAuthErrorProviderAlreadyLinked); id_token_listener.VerifyAndReset(); @@ -662,13 +662,13 @@ TEST_F(UserDesktopTest, TestLinkWithCredential_ChecksAlreadyLinkedProviders) { // Should be able to link a different provider. const Credential facebook_credential = FacebookAuthProvider::GetCredential("fake_access_token"); - WaitForFuture(firebase_user_->LinkWithCredential(facebook_credential)); + WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(facebook_credential)); // The same provider shouldn't be linked twice. - WaitForFuture(firebase_user_->LinkWithCredential(facebook_credential), + WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(facebook_credential), kAuthErrorProviderAlreadyLinked); // Check that the previously linked provider wasn't overridden. - WaitForFuture(firebase_user_->LinkWithCredential(google_credential), + WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(google_credential), kAuthErrorProviderAlreadyLinked); } @@ -727,7 +727,7 @@ TEST_F(UserDesktopTest, TestReauthenticateAndRetrieveData) { const Credential credential = GoogleAuthProvider::GetCredential("fake_id_token", ""); const SignInResult sign_in_result = - WaitForFuture(firebase_user_->ReauthenticateAndRetrieveData(credential)); + WaitForFuture(firebase_user_->ReauthenticateAndRetrieveData_DEPRECATED(credential)); EXPECT_FALSE(sign_in_result.user->is_anonymous()); VerifyUser(*sign_in_result.user); } @@ -830,7 +830,7 @@ TEST_F(UserDesktopTestSignOutOnError, Unlink) { GetUrlForApi(API_KEY, "setAccountInfo"), "USER_NOT_FOUND", kAuthErrorUserNotFound, [&] { sem_.Post(); - return firebase_user_->Unlink("fake_provider_id"); + return firebase_user_->Unlink_DEPRECATED("fake_provider_id"); }); sem_.Wait(); } @@ -840,7 +840,7 @@ TEST_F(UserDesktopTestSignOutOnError, LinkWithEmail) { GetUrlForApi(API_KEY, "setAccountInfo"), "USER_NOT_FOUND", kAuthErrorUserNotFound, [&] { sem_.Post(); - return firebase_user_->LinkWithCredential( + return firebase_user_->LinkWithCredential_DEPRECATED( EmailAuthProvider::GetCredential("fake_email@example.com", "fake_password")); }); @@ -852,7 +852,7 @@ TEST_F(UserDesktopTestSignOutOnError, LinkWithOauthCredential) { GetUrlForApi(API_KEY, "verifyAssertion"), "USER_NOT_FOUND", kAuthErrorUserNotFound, [&] { sem_.Post(); - return firebase_user_->LinkWithCredential( + return firebase_user_->LinkWithCredential_DEPRECATED( GoogleAuthProvider::GetCredential("fake_id_token", "")); }); sem_.Wait(); @@ -896,7 +896,7 @@ TEST_F(UserDesktopTest, TestRaceCondition_SetAccountInfoAndSignOut) { // LinkWithProvider tests. TEST_F(UserDesktopTest, TestLinkWithProviderReturnsUnsupportedError) { FederatedOAuthProvider provider; - Future future = firebase_user_->LinkWithProvider(&provider); + Future future = firebase_user_->LinkWithProvider_DEPRECATED(&provider); EXPECT_EQ(future.result()->user, nullptr); EXPECT_EQ(future.error(), kAuthErrorUnimplemented); EXPECT_EQ(std::string(future.error_message()), @@ -911,7 +911,7 @@ TEST_F(UserDesktopTest, test::OAuthProviderTestHandler handler(/*extra_integrity_checks_=*/true); InitializeSuccessfulAuthenticateWithProviderFlow(&provider, &handler); - Future future = firebase_user_->LinkWithProvider(&provider); + Future future = firebase_user_->LinkWithProvider_DEPRECATED(&provider); handler.TriggerLinkComplete(); SignInResult sign_in_result = WaitForFuture(future); } @@ -927,9 +927,9 @@ TEST_F(UserDesktopTest, OAuthProviderTestHandler handler2; provider2.SetAuthHandler(&handler2); - Future future1 = firebase_user_->LinkWithProvider(&provider1); + Future future1 = firebase_user_->LinkWithProvider_DEPRECATED(&provider1); EXPECT_EQ(future1.status(), kFutureStatusPending); - Future future2 = firebase_user_->LinkWithProvider(&provider2); + Future future2 = firebase_user_->LinkWithProvider_DEPRECATED(&provider2); VerifySignInResult(future2, kAuthErrorFederatedProviderAreadyInUse); handler1.TriggerLinkComplete(); const SignInResult sign_in_result = WaitForFuture(future1); @@ -1056,7 +1056,7 @@ TEST_F(UserDesktopTest, DISABLED_TestLinkCompleteNullErrorMessageFails) { TEST_F(UserDesktopTest, TestReauthentciateWithProviderReturnsUnsupportedError) { FederatedOAuthProvider provider; Future future = - firebase_user_->ReauthenticateWithProvider(&provider); + firebase_user_->ReauthenticateWithProvider_DEPRECATED(&provider); EXPECT_EQ(future.result()->user, nullptr); EXPECT_EQ(future.error(), kAuthErrorUnimplemented); EXPECT_EQ(std::string(future.error_message()), @@ -1073,7 +1073,7 @@ TEST_F( InitializeSuccessfulAuthenticateWithProviderFlow(&provider, &handler); Future future = - firebase_user_->ReauthenticateWithProvider(&provider); + firebase_user_->ReauthenticateWithProvider_DEPRECATED(&provider); handler.TriggerReauthenticateComplete(); SignInResult sign_in_result = WaitForFuture(future); } @@ -1090,10 +1090,10 @@ TEST_F(UserDesktopTest, OAuthProviderTestHandler handler2; provider2.SetAuthHandler(&handler2); Future future1 = - firebase_user_->ReauthenticateWithProvider(&provider1); + firebase_user_->ReauthenticateWithProvider_DEPRECATED(&provider1); EXPECT_EQ(future1.status(), kFutureStatusPending); Future future2 = - firebase_user_->ReauthenticateWithProvider(&provider2); + firebase_user_->ReauthenticateWithProvider_DEPRECATED(&provider2); VerifySignInResult(future2, kAuthErrorFederatedProviderAreadyInUse); handler1.TriggerReauthenticateComplete(); const SignInResult sign_in_result = WaitForFuture(future1); diff --git a/auth/tests/user_test.cc b/auth/tests/user_test.cc index e9373b477c..21c9df13c5 100644 --- a/auth/tests/user_test.cc +++ b/auth/tests/user_test.cc @@ -368,7 +368,7 @@ TEST_F(UserTest, TestReauthenticateAndRetrieveData) { "}"; firebase::testing::cppsdk::ConfigSet(config.c_str()); - Future result = firebase_user_->ReauthenticateAndRetrieveData( + Future result = firebase_user_->ReauthenticateAndRetrieveData_DEPRECATED( EmailAuthProvider::GetCredential("i@email.com", "pw")); Verify(result); } @@ -414,7 +414,7 @@ TEST_F(UserTest, TestLinkWithCredential) { "}"; firebase::testing::cppsdk::ConfigSet(config.c_str()); - Future result = firebase_user_->LinkWithCredential( + Future result = firebase_user_->LinkWithCredential_DEPRECATED( EmailAuthProvider::GetCredential("i@email.com", "pw")); Verify(result); } @@ -422,7 +422,7 @@ TEST_F(UserTest, TestLinkWithCredential) { #if !defined(__APPLE__) && !defined(FIREBASE_WAIT_ASYNC_IN_TEST) TEST_F(UserTest, TestLinkAndRetrieveDataWithCredential) { // Test link and retrieve data with credential. This calls the same native SDK - // function as LinkWithCredential(). + // function as LinkWithCredential_DEPRECATED(). firebase::testing::cppsdk::ConfigSet( "{" " config:[" @@ -461,7 +461,7 @@ TEST_F(UserTest, TestUnlink) { // MaybeWaitForFuture because to Reload will return immediately for mobile // wrappers, and Verify expects at least a single "tick". MaybeWaitForFuture(firebase_user_->Reload()); - Future result = firebase_user_->Unlink("provider"); + Future result = firebase_user_->Unlink_DEPRECATED("provider"); Verify(result); // For desktop, the provider must have been removed. For mobile wrappers, the // whole flow must have been a no-op, and the provider list was empty to begin From e7ad4aabc3021f1541a1df1d3a11b1982392b552 Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Sun, 12 Mar 2023 14:06:09 -0400 Subject: [PATCH 03/14] FirebaseAuth.java and auth_test.cc fixes --- auth/src/android/auth_android.cc | 4 ++-- .../fake/com/google/firebase/auth/FirebaseAuth.java | 6 +++--- auth/tests/auth_test.cc | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index 7888e52b90..db008a8995 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -67,7 +67,7 @@ using util::JniStringToString; X(SignInWithEmailAndPassword, "signInWithEmailAndPassword", \ "(Ljava/lang/String;Ljava/lang/String;)" \ "Lcom/google/android/gms/tasks/Task;"), \ - X(CreateUserWithEmailAndPassword_DEPRECATED, "createUserWithEmailAndPassword_DEPRECATED", \ + X(CreateUserWithEmailAndPassword, "createUserWithEmailAndPassword", \ "(Ljava/lang/String;Ljava/lang/String;)" \ "Lcom/google/android/gms/tasks/Task;"), \ X(SendPasswordResetEmail, "sendPasswordResetEmail", \ @@ -533,7 +533,7 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char* email, jstring j_password = env->NewStringUTF(password); jobject pending_result = env->CallObjectMethod( AuthImpl(auth_data_), - auth::GetMethodId(auth::kCreateUserWithEmailAndPassword_DEPRECATED), j_email, + auth::GetMethodId(auth::kCreateUserWithEmailAndPassword), j_email, j_password); env->DeleteLocalRef(j_email); env->DeleteLocalRef(j_password); diff --git a/auth/src_java/fake/com/google/firebase/auth/FirebaseAuth.java b/auth/src_java/fake/com/google/firebase/auth/FirebaseAuth.java index c1ee9b1193..3dabb3aa90 100644 --- a/auth/src_java/fake/com/google/firebase/auth/FirebaseAuth.java +++ b/auth/src_java/fake/com/google/firebase/auth/FirebaseAuth.java @@ -186,7 +186,7 @@ public Task signInWithCredential(AuthCredential credential) { return signInHelper("FirebaseAuth.signInWithCredential"); } - public Task signInAnonymously_DEPRECATED() { + public Task signInAnonymously() { return signInHelper("FirebaseAuth.signInAnonymously"); } @@ -227,8 +227,8 @@ public Task startActivityForSignInWithProvider( return signInHelper("FirebaseAuth.startActivityForSignInWithProvider"); } - public Task createUserWithEmailAndPassword_DEPRECATED(String email, String password) { - return signInHelper("FirebaseAuth.createUserWithEmailAndPassword_DEPRECATED"); + public Task createUserWithEmailAndPassword(String email, String password) { + return signInHelper("FirebaseAuth.createUserWithEmailAndPassword"); } public Task sendPasswordResetEmail(String email) { diff --git a/auth/tests/auth_test.cc b/auth/tests/auth_test.cc index 24b774dae2..5d88957ca9 100644 --- a/auth/tests/auth_test.cc +++ b/auth/tests/auth_test.cc @@ -325,7 +325,7 @@ TEST_F(AuthTest, TestCreateUserWithEmailAndPasswordSucceeded) { firebase::testing::cppsdk::ConfigSet( "{" " config:[" - " {fake:'FirebaseAuth.createUserWithEmailAndPassword_DEPRECATED'," + " {fake:'FirebaseAuth.createUserWithEmailAndPassword'," " futuregeneric:{ticker:1}}," " {fake:'FIRAuth.createUserWithEmail:password:completion:'," " futuregeneric:{ticker:1}}," @@ -454,7 +454,7 @@ TEST_F(AuthTest, TestCreateUserWithEmailAndPasswordFailed) { firebase::testing::cppsdk::ConfigSet( "{" " config:[" - " {fake:'FirebaseAuth.createUserWithEmailAndPassword_DEPRECATED'," + " {fake:'FirebaseAuth.createUserWithEmailAndPassword'," " futuregeneric:{throwexception:true," " " "exceptionmsg:'[FirebaseAuthUserCollisionException:ERROR_EMAIL_ALREADY_" From 16ec67877f58a83b4d3aa3f5e39d9226380a34b5 Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Sun, 12 Mar 2023 14:06:44 -0400 Subject: [PATCH 04/14] format --- auth/integration_test/src/integration_test.cc | 155 ++++++++++-------- auth/samples/src/doc_samples.cc | 11 +- auth/src/android/auth_android.cc | 27 +-- auth/src/android/credential_android.cc | 4 +- auth/src/android/user_android.cc | 13 +- auth/src/auth.cc | 7 +- auth/src/common.h | 9 +- auth/src/desktop/auth_desktop.cc | 29 ++-- .../auth_providers/federated_auth_provider.cc | 4 +- auth/src/desktop/authentication_result.cc | 3 +- auth/src/desktop/user_desktop.cc | 23 ++- auth/src/include/firebase/auth.h | 62 ++++--- auth/src/include/firebase/auth/user.h | 41 +++-- auth/src/ios/auth_ios.mm | 22 ++- auth/src/ios/credential_ios.mm | 9 +- auth/src/ios/user_ios.mm | 3 +- auth/tests/auth_test.cc | 26 +-- auth/tests/desktop/auth_desktop_test.cc | 70 ++++---- auth/tests/desktop/user_desktop_test.cc | 49 ++++-- auth/tests/user_test.cc | 5 +- 20 files changed, 340 insertions(+), 232 deletions(-) diff --git a/auth/integration_test/src/integration_test.cc b/auth/integration_test/src/integration_test.cc index 2cfdc82a3d..d7d4abd443 100644 --- a/auth/integration_test/src/integration_test.cc +++ b/auth/integration_test/src/integration_test.cc @@ -312,8 +312,9 @@ class TestAuthStateListener : public firebase::auth::AuthStateListener { public: virtual void OnAuthStateChanged(firebase::auth::Auth* auth) { // NOLINT // Log the provider ID. - std::string provider = - auth->current_user_DEPRECATED() ? auth->current_user_DEPRECATED()->provider_id() : ""; + std::string provider = auth->current_user_DEPRECATED() + ? auth->current_user_DEPRECATED()->provider_id() + : ""; LogDebug("OnAuthStateChanged called, provider=%s", provider.c_str()); if (auth_states_.empty() || auth_states_.back() != provider) { // Only log unique events. @@ -409,7 +410,8 @@ TEST_F(FirebaseAuthTest, TestEmailAndPasswordSignin) { // Register a random email and password. This signs us in as that user. std::string password = kTestPassword; firebase::Future create_user = - auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), password.c_str()); + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), + password.c_str()); WaitForCompletion(create_user, "CreateUserWithEmailAndPassword_DEPRECATED"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); // Sign out and log in using SignInWithCredential_DEPRECATED(EmailCredential). @@ -437,15 +439,18 @@ TEST_F(FirebaseAuthTest, TestEmailAndPasswordSignin) { SignOut(); // Sign in with SignInWithEmailAndPassword values. firebase::Future sign_in_user = - auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), password.c_str()); + auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), + password.c_str()); WaitForCompletion(sign_in_user, "SignInWithEmailAndPassword"); ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); // Then delete the account. - firebase::Future delete_user = auth_->current_user_DEPRECATED()->Delete(); + firebase::Future delete_user = + auth_->current_user_DEPRECATED()->Delete(); WaitForCompletion(delete_user, "Delete"); firebase::Future invalid_sign_in_user = - auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), password.c_str()); + auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), + password.c_str()); WaitForCompletion(invalid_sign_in_user, "SignInWithEmailAndPassword (invalid user)", firebase::auth::kAuthErrorUserNotFound); @@ -455,7 +460,8 @@ TEST_F(FirebaseAuthTest, TestEmailAndPasswordSignin) { TEST_F(FirebaseAuthTest, TestUpdateUserProfile) { std::string email = GenerateEmailAddress(); firebase::Future create_user = - auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword); + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), + kTestPassword); WaitForCompletion(create_user, "CreateUserWithEmailAndPassword_DEPRECATED"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); // Set some user profile properties. @@ -470,9 +476,9 @@ TEST_F(FirebaseAuthTest, TestUpdateUserProfile) { EXPECT_EQ(user->display_name(), kDisplayName); EXPECT_EQ(user->photo_url(), kPhotoUrl); SignOut(); - WaitForCompletion( - auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "SignInWithEmailAndPassword"); + WaitForCompletion(auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), + kTestPassword), + "SignInWithEmailAndPassword"); EXPECT_EQ(user->display_name(), kDisplayName); EXPECT_EQ(user->photo_url(), kPhotoUrl); DeleteUser(); @@ -480,9 +486,9 @@ TEST_F(FirebaseAuthTest, TestUpdateUserProfile) { TEST_F(FirebaseAuthTest, TestUpdateEmailAndPassword) { std::string email = GenerateEmailAddress(); - WaitForCompletion( - auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword_DEPRECATED"); + WaitForCompletion(auth_->CreateUserWithEmailAndPassword_DEPRECATED( + email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED"); ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); firebase::auth::User* user = auth_->current_user_DEPRECATED(); @@ -512,7 +518,8 @@ TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithEmailCredential) { kTestPassword); WaitForCompletion(user->LinkAndRetrieveDataWithCredential(credential), "LinkAndRetrieveDataWithCredential"); - WaitForCompletion(user->Unlink_DEPRECATED(credential.provider().c_str()), "Unlink"); + WaitForCompletion(user->Unlink_DEPRECATED(credential.provider().c_str()), + "Unlink"); SignOut(); WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); @@ -529,7 +536,8 @@ TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithEmailCredential) { WaitForCompletion(user->LinkWithCredential_DEPRECATED(credential2), "LinkWithCredential 2", firebase::auth::kAuthErrorProviderAlreadyLinked); - WaitForCompletion(user->Unlink_DEPRECATED(credential.provider().c_str()), "Unlink 2"); + WaitForCompletion(user->Unlink_DEPRECATED(credential.provider().c_str()), + "Unlink 2"); DeleteUser(); } @@ -549,55 +557,57 @@ TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithBadCredential) { } TEST_F(FirebaseAuthTest, TestSignInWithBadEmailFails) { - WaitForCompletion( - auth_->SignInWithEmailAndPassword_DEPRECATED(kTestEmailBad, kTestPassword), - "SignInWithEmailAndPassword", firebase::auth::kAuthErrorUserNotFound); + WaitForCompletion(auth_->SignInWithEmailAndPassword_DEPRECATED(kTestEmailBad, + kTestPassword), + "SignInWithEmailAndPassword", + firebase::auth::kAuthErrorUserNotFound); EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); } TEST_F(FirebaseAuthTest, TestSignInWithBadPasswordFails) { std::string email = GenerateEmailAddress(); - WaitForCompletion( - auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword_DEPRECATED"); + WaitForCompletion(auth_->CreateUserWithEmailAndPassword_DEPRECATED( + email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); SignOut(); - WaitForCompletion( - auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPasswordBad), - "SignInWithEmailAndPassword", firebase::auth::kAuthErrorWrongPassword); + WaitForCompletion(auth_->SignInWithEmailAndPassword_DEPRECATED( + email.c_str(), kTestPasswordBad), + "SignInWithEmailAndPassword", + firebase::auth::kAuthErrorWrongPassword); EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); SignOut(); // Sign back in and delete the user. - WaitForCompletion( - auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "SignInWithEmailAndPassword"); + WaitForCompletion(auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), + kTestPassword), + "SignInWithEmailAndPassword"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); DeleteUser(); } TEST_F(FirebaseAuthTest, TestCreateUserWithExistingEmailFails) { std::string email = GenerateEmailAddress(); - WaitForCompletion( - auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword_DEPRECATED 1"); + WaitForCompletion(auth_->CreateUserWithEmailAndPassword_DEPRECATED( + email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED 1"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); SignOut(); - WaitForCompletion( - auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword_DEPRECATED 2", - firebase::auth::kAuthErrorEmailAlreadyInUse); + WaitForCompletion(auth_->CreateUserWithEmailAndPassword_DEPRECATED( + email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED 2", + firebase::auth::kAuthErrorEmailAlreadyInUse); EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); SignOut(); // Try again with a different password. - WaitForCompletion( - auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPasswordBad), - "CreateUserWithEmailAndPassword_DEPRECATED 3", - firebase::auth::kAuthErrorEmailAlreadyInUse); + WaitForCompletion(auth_->CreateUserWithEmailAndPassword_DEPRECATED( + email.c_str(), kTestPasswordBad), + "CreateUserWithEmailAndPassword_DEPRECATED 3", + firebase::auth::kAuthErrorEmailAlreadyInUse); EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); SignOut(); - WaitForCompletion( - auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "SignInWithEmailAndPassword"); + WaitForCompletion(auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), + kTestPassword), + "SignInWithEmailAndPassword"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); DeleteUser(); } @@ -641,8 +651,9 @@ TEST_F(FirebaseAuthTest, TestSignInWithBadCredentials) { firebase::auth::kAuthErrorInvalidCredential); EXPECT_EQ(auth_->current_user_DEPRECATED(), existing_user); WaitForCompletion( - auth_->SignInWithCredential_DEPRECATED(firebase::auth::OAuthProvider::GetCredential( - kTestIdProviderIdBad, kTestIdTokenBad, kTestAccessTokenBad)), + auth_->SignInWithCredential_DEPRECATED( + firebase::auth::OAuthProvider::GetCredential( + kTestIdProviderIdBad, kTestIdTokenBad, kTestAccessTokenBad)), "SignInWithCredential (OAuth)", firebase::auth::kAuthErrorFailure); EXPECT_EQ(auth_->current_user_DEPRECATED(), existing_user); @@ -674,8 +685,9 @@ TEST_F(FirebaseAuthTest, TestGameCenterSignIn) { EXPECT_NE(credential_future.result(), nullptr); if (credential_future.result()) { - WaitForCompletion(auth_->SignInWithCredential_DEPRECATED(*credential_future.result()), - "SignInWithCredential (Game Center)"); + WaitForCompletion( + auth_->SignInWithCredential_DEPRECATED(*credential_future.result()), + "SignInWithCredential (Game Center)"); } DeleteUser(); } @@ -684,9 +696,9 @@ TEST_F(FirebaseAuthTest, TestGameCenterSignIn) { TEST_F(FirebaseAuthTest, TestSendPasswordResetEmail) { // Test Auth::SendPasswordResetEmail(). std::string email = GenerateEmailAddress(); - WaitForCompletion( - auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword_DEPRECATED"); + WaitForCompletion(auth_->CreateUserWithEmailAndPassword_DEPRECATED( + email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); SignOut(); // Send to correct email. @@ -697,9 +709,9 @@ TEST_F(FirebaseAuthTest, TestSendPasswordResetEmail) { "SendPasswordResetEmail (bad)", firebase::auth::kAuthErrorUserNotFound); // Delete user now that we are done with it. - WaitForCompletion( - auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "SignInWithEmailAndPassword"); + WaitForCompletion(auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), + kTestPassword), + "SignInWithEmailAndPassword"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); DeleteUser(); } @@ -714,7 +726,8 @@ TEST_F(FirebaseAuthTest, TestWithCustomEmailAndPassword) { return; } firebase::Future sign_in_user = - auth_->SignInWithEmailAndPassword_DEPRECATED(kCustomTestEmail, kCustomTestPassword); + auth_->SignInWithEmailAndPassword_DEPRECATED(kCustomTestEmail, + kCustomTestPassword); WaitForCompletion(sign_in_user, "SignInWithEmailAndPassword"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); } @@ -745,16 +758,18 @@ TEST_F(FirebaseAuthTest, TestAuthPersistenceWithEmailSignin) { FLAKY_TEST_SECTION_BEGIN(); std::string email = GenerateEmailAddress(); - WaitForCompletion( - auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "CreateUserWithEmailAndPassword_DEPRECATED"); + WaitForCompletion(auth_->CreateUserWithEmailAndPassword_DEPRECATED( + email.c_str(), kTestPassword), + "CreateUserWithEmailAndPassword_DEPRECATED"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); EXPECT_FALSE(auth_->current_user_DEPRECATED()->is_anonymous()); - std::string prev_provider_id = auth_->current_user_DEPRECATED()->provider_id(); + std::string prev_provider_id = + auth_->current_user_DEPRECATED()->provider_id(); // Save the old provider ID list so we can make sure it's the same once // it's loaded again. std::vector prev_provider_data_ids; - for (int i = 0; i < auth_->current_user_DEPRECATED()->provider_data().size(); i++) { + for (int i = 0; i < auth_->current_user_DEPRECATED()->provider_data().size(); + i++) { prev_provider_data_ids.push_back( auth_->current_user_DEPRECATED()->provider_data()[i]->provider_id()); } @@ -767,16 +782,17 @@ TEST_F(FirebaseAuthTest, TestAuthPersistenceWithEmailSignin) { // Make sure the provider IDs are the same as they were before. EXPECT_EQ(auth_->current_user_DEPRECATED()->provider_id(), prev_provider_id); std::vector loaded_provider_data_ids; - for (int i = 0; i < auth_->current_user_DEPRECATED()->provider_data().size(); i++) { + for (int i = 0; i < auth_->current_user_DEPRECATED()->provider_data().size(); + i++) { loaded_provider_data_ids.push_back( auth_->current_user_DEPRECATED()->provider_data()[i]->provider_id()); } EXPECT_TRUE(loaded_provider_data_ids == prev_provider_data_ids); // Cleanup, ensure we are signed in as the user so we can delete it. - WaitForCompletion( - auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), kTestPassword), - "SignInWithEmailAndPassword"); + WaitForCompletion(auth_->SignInWithEmailAndPassword_DEPRECATED(email.c_str(), + kTestPassword), + "SignInWithEmailAndPassword"); EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); DeleteUser(); @@ -904,8 +920,9 @@ TEST_F(FirebaseAuthTest, TestPhoneAuth) { } if (listener.on_verification_complete_count() > 0) { LogDebug("Signing in with automatic verification code."); - WaitForCompletion(auth_->SignInWithCredential_DEPRECATED(listener.credential()), - "SignInWithCredential_DEPRECATED(PhoneCredential) automatic"); + WaitForCompletion( + auth_->SignInWithCredential_DEPRECATED(listener.credential()), + "SignInWithCredential_DEPRECATED(PhoneCredential) automatic"); } else if (listener.on_verification_failed_count() > 0) { FAIL() << "Automatic verification failed."; } else { @@ -1008,7 +1025,8 @@ TEST_F(FirebaseAuthTest, TestSuccessfulReauthenticateWithProvider) { auth_->SignInWithProvider_DEPRECATED(&provider); if (WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id)) { WaitForCompletion( - sign_in_future.result()->user->ReauthenticateWithProvider_DEPRECATED(&provider), + sign_in_future.result()->user->ReauthenticateWithProvider_DEPRECATED( + &provider), "ReauthenticateWithProvider", provider_id); } DeleteUser(); @@ -1027,7 +1045,8 @@ TEST_F(FirebaseAuthTest, TestSuccessfulReauthenticateWithProviderNoScopes) { auth_->SignInWithProvider_DEPRECATED(&provider); if (WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id)) { WaitForCompletion( - sign_in_future.result()->user->ReauthenticateWithProvider_DEPRECATED(&provider), + sign_in_future.result()->user->ReauthenticateWithProvider_DEPRECATED( + &provider), "ReauthenticateWithProvider", provider_id); } DeleteUser(); @@ -1047,7 +1066,8 @@ TEST_F(FirebaseAuthTest, auth_->SignInWithProvider_DEPRECATED(&provider); if (WaitForCompletion(sign_in_future, "SignInWithProvider", provider_id)) { WaitForCompletion( - sign_in_future.result()->user->ReauthenticateWithProvider_DEPRECATED(&provider), + sign_in_future.result()->user->ReauthenticateWithProvider_DEPRECATED( + &provider), "ReauthenticateWithProvider", provider_id); } DeleteUser(); @@ -1067,7 +1087,8 @@ TEST_F(FirebaseAuthTest, TestReauthenticateWithProviderBadProviderIdFails) { provider_data.provider_id = "MadeUpProvider"; firebase::auth::FederatedOAuthProvider provider(provider_data); firebase::Future reauth_future = - auth_->current_user_DEPRECATED()->ReauthenticateWithProvider_DEPRECATED(&provider); + auth_->current_user_DEPRECATED()->ReauthenticateWithProvider_DEPRECATED( + &provider); WaitForCompletion(reauth_future, "ReauthenticateWithProvider", firebase::auth::kAuthErrorInvalidProviderId); } diff --git a/auth/samples/src/doc_samples.cc b/auth/samples/src/doc_samples.cc index db80756f3d..3a49f27506 100644 --- a/auth/samples/src/doc_samples.cc +++ b/auth/samples/src/doc_samples.cc @@ -196,7 +196,8 @@ void VariousSignIns(firebase::auth::Auth* auth) { } { // [START auth_sign_in_anonymously] - firebase::Future result = auth->SignInAnonymously_DEPRECATED(); + firebase::Future result = + auth->SignInAnonymously_DEPRECATED(); // [END auth_sign_in_anonymously] (void)result; } @@ -549,7 +550,8 @@ void LinkCredentialFailAppleSignIn(const firebase::auth::Credential& credential, firebase::auth::Auth* auth) { // [START link_credential_apple_signin] firebase::Future link_result = - auth->current_user_DEPRECATED()->LinkAndRetrieveDataWithCredential(credential); + auth->current_user_DEPRECATED()->LinkAndRetrieveDataWithCredential( + credential); // To keep example simple, wait on the current thread until call completes. while (link_result.status() == firebase::kFutureStatusPending) { @@ -563,8 +565,9 @@ void LinkCredentialFailAppleSignIn(const firebase::auth::Credential& credential, firebase::auth::kAuthErrorCredentialAlreadyInUse && link_result.result()->info.updated_credential.is_valid()) { // Sign In with the new credential - firebase::Future result = auth->SignInWithCredential_DEPRECATED( - link_result.result()->info.updated_credential); + firebase::Future result = + auth->SignInWithCredential_DEPRECATED( + link_result.result()->info.updated_credential); } else { // Another link error occurred. } diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index db008a8995..4691b3ada6 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -395,7 +395,8 @@ Future Auth::FetchProvidersForEmail( Future Auth::SignInWithCustomToken_DEPRECATED(const char* token) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED); + const auto handle = + futures.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED); JNIEnv* env = Env(auth_data_); jstring j_token = env->NewStringUTF(token); @@ -412,9 +413,11 @@ Future Auth::SignInWithCustomToken_DEPRECATED(const char* token) { return MakeFuture(&futures, handle); } -Future Auth::SignInWithCredential_DEPRECATED(const Credential& credential) { +Future Auth::SignInWithCredential_DEPRECATED( + const Credential& credential) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED); + const auto handle = + futures.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED); JNIEnv* env = Env(auth_data_); // If the credential itself is in an error state, don't try signing in. @@ -459,14 +462,16 @@ Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( return MakeFuture(&futures, handle); } -Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider* provider) { +Future Auth::SignInWithProvider_DEPRECATED( + FederatedAuthProvider* provider) { FIREBASE_ASSERT_RETURN(Future(), provider); return provider->SignIn(auth_data_); } Future Auth::SignInAnonymously_DEPRECATED() { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED); + const auto handle = + futures.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED); JNIEnv* env = Env(auth_data_); jobject pending_result = env->CallObjectMethod( @@ -481,8 +486,8 @@ Future Auth::SignInAnonymously_DEPRECATED() { return MakeFuture(&futures, handle); } -Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char* email, - const char* password) { +Future Auth::SignInWithEmailAndPassword_DEPRECATED( + const char* email, const char* password) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED); @@ -514,11 +519,11 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char* email, return MakeFuture(&futures, handle); } -Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char* email, - const char* password) { +Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( + const char* email, const char* password) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED); + const auto handle = futures.SafeAlloc( + kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED); if (!email || strlen(email) == 0 || !password || strlen(password) == 0) { futures.Complete(handle, diff --git a/auth/src/android/credential_android.cc b/auth/src/android/credential_android.cc index 930f8bae48..e9512f9bf6 100644 --- a/auth/src/android/credential_android.cc +++ b/auth/src/android/credential_android.cc @@ -1038,8 +1038,8 @@ Future FederatedOAuthProvider::Link(AuthData* auth_data) { assert(auth_data); JNIEnv* env = Env(auth_data); ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = - futures.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + const auto handle = futures.SafeAlloc( + kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { diff --git a/auth/src/android/user_android.cc b/auth/src/android/user_android.cc index ab4efcee39..2df7db018e 100644 --- a/auth/src/android/user_android.cc +++ b/auth/src/android/user_android.cc @@ -466,12 +466,14 @@ Future User::UpdateUserProfile(const UserProfile& profile) { return MakeFuture(&futures, handle); } -Future User::LinkWithCredential_DEPRECATED(const Credential& credential) { +Future User::LinkWithCredential_DEPRECATED( + const Credential& credential) { if (!ValidUser(auth_data_)) { return Future(); } ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_LinkWithCredential_DEPRECATED); + const auto handle = + futures.SafeAlloc(kUserFn_LinkWithCredential_DEPRECATED); JNIEnv* env = Env(auth_data_); jobject pending_result = env->CallObjectMethod( @@ -534,7 +536,8 @@ Future User::Unlink_DEPRECATED(const char* provider) { return MakeFuture(&futures, handle); } -Future User::UpdatePhoneNumberCredential_DEPRECATED(const Credential& credential) { +Future User::UpdatePhoneNumberCredential_DEPRECATED( + const Credential& credential) { if (!ValidUser(auth_data_)) { return Future(); } @@ -604,8 +607,8 @@ Future User::ReauthenticateAndRetrieveData_DEPRECATED( return Future(); } ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); + const auto handle = futures.SafeAlloc( + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); JNIEnv* env = Env(auth_data_); jobject pending_result = env->CallObjectMethod( diff --git a/auth/src/auth.cc b/auth/src/auth.cc index 8760439dd5..fe92cd421d 100644 --- a/auth/src/auth.cc +++ b/auth/src/auth.cc @@ -227,8 +227,8 @@ void Auth::AddAuthStateListener(AuthStateListener* listener) { // If the listener is registered successfully and persistent cache has been // loaded, trigger OnAuthStateChanged() immediately. Otherwise, wait until // the cache is loaded, through AuthStateListener event. - // NOTE: This should be called synchronously or current_user_DEPRECATED() for desktop - // implementation may not work. + // NOTE: This should be called synchronously or current_user_DEPRECATED() for + // desktop implementation may not work. if (added && !auth_data_->persistent_cache_load_pending) { listener->OnAuthStateChanged(this); } @@ -368,7 +368,8 @@ AUTH_RESULT_FN(Auth, SendPasswordResetEmail, void) AUTH_RESULT_DEPRECATED_FN(Auth, SignInWithCustomToken, User*) AUTH_RESULT_DEPRECATED_FN(Auth, SignInWithCredential, User*) -AUTH_RESULT_DEPRECATED_FN(Auth, SignInAndRetrieveDataWithCredential, SignInResult) +AUTH_RESULT_DEPRECATED_FN(Auth, SignInAndRetrieveDataWithCredential, + SignInResult) AUTH_RESULT_DEPRECATED_FN(Auth, SignInAnonymously, User*) AUTH_RESULT_DEPRECATED_FN(Auth, SignInWithEmailAndPassword, User*) AUTH_RESULT_DEPRECATED_FN(Auth, CreateUserWithEmailAndPassword, User*) diff --git a/auth/src/common.h b/auth/src/common.h index 8e09dd08fb..dc70768108 100644 --- a/auth/src/common.h +++ b/auth/src/common.h @@ -53,10 +53,11 @@ void LogHeartbeat(Auth* auth); // All the result functions are similar. // Just return the local Future, cast to the proper result type. -#define AUTH_RESULT_DEPRECATED_FN(class_name, fn_name, result_type) \ - Future class_name::fn_name##LastResult_DEPRECATED() const { \ - return static_cast&>( \ - auth_data_->future_impl.LastResult(k##class_name##Fn_##fn_name##_DEPRECATED)); \ +#define AUTH_RESULT_DEPRECATED_FN(class_name, fn_name, result_type) \ + Future class_name::fn_name##LastResult_DEPRECATED() const { \ + return static_cast&>( \ + auth_data_->future_impl.LastResult( \ + k##class_name##Fn_##fn_name##_DEPRECATED)); \ } // Returns true if `auth_data` has a user that's currently active. diff --git a/auth/src/desktop/auth_desktop.cc b/auth/src/desktop/auth_desktop.cc index 80d03e4549..2eb756443b 100644 --- a/auth/src/desktop/auth_desktop.cc +++ b/auth/src/desktop/auth_desktop.cc @@ -337,7 +337,8 @@ void Auth::DestroyPlatformAuth(AuthData* const auth_data) { // RPCs -Future Auth::SignInWithCustomToken_DEPRECATED(const char* const custom_token) { +Future Auth::SignInWithCustomToken_DEPRECATED( + const char* const custom_token) { Promise promise(&auth_data_->future_impl, kAuthFn_SignInWithCustomToken_DEPRECATED); if (!custom_token || strlen(custom_token) == 0) { @@ -355,7 +356,8 @@ Future Auth::SignInWithCustomToken_DEPRECATED(const char* const custom_to PerformSignInFlow); } -Future Auth::SignInWithCredential_DEPRECATED(const Credential& credential) { +Future Auth::SignInWithCredential_DEPRECATED( + const Credential& credential) { Promise promise(&auth_data_->future_impl, kAuthFn_SignInWithCredential_DEPRECATED); if (!ValidateCredential(&promise, credential.provider(), credential.impl_)) { @@ -366,7 +368,8 @@ Future Auth::SignInWithCredential_DEPRECATED(const Credential& credential credential.impl_); } -Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider* provider) { +Future Auth::SignInWithProvider_DEPRECATED( + FederatedAuthProvider* provider) { FIREBASE_ASSERT_RETURN(Future(), provider); // TODO(b/139363200) // return provider->SignIn(auth_data_); @@ -382,7 +385,8 @@ Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider* } Future Auth::SignInAnonymously_DEPRECATED() { - Promise promise(&auth_data_->future_impl, kAuthFn_SignInAnonymously_DEPRECATED); + Promise promise(&auth_data_->future_impl, + kAuthFn_SignInAnonymously_DEPRECATED); // If user is already signed in anonymously, return immediately. bool is_anonymous = false; @@ -405,8 +409,8 @@ Future Auth::SignInAnonymously_DEPRECATED() { PerformSignInFlow); } -Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char* const email, - const char* const password) { +Future Auth::SignInWithEmailAndPassword_DEPRECATED( + const char* const email, const char* const password) { Promise promise(&auth_data_->future_impl, kAuthFn_SignInWithEmailAndPassword_DEPRECATED); if (!ValidateEmailAndPassword(&promise, email, password)) { @@ -421,8 +425,8 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char* const emai PerformSignInFlow); } -Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char* const email, - const char* const password) { +Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( + const char* const email, const char* const password) { Promise promise(&auth_data_->future_impl, kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED); if (!ValidateEmailAndPassword(&promise, email, password)) { @@ -440,8 +444,9 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char* const Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential& credential) { - Promise promise(&auth_data_->future_impl, - kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED); + Promise promise( + &auth_data_->future_impl, + kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED); return DoSignInWithCredential(promise, auth_data_, credential.provider(), credential.impl_); } @@ -509,8 +514,8 @@ void Auth::SignOut() { AuthenticationResult::SignOut(auth_data_); } -// AuthStateListener to wait for current_user_DEPRECATED() until persistent cache load is -// finished. +// AuthStateListener to wait for current_user_DEPRECATED() until persistent +// cache load is finished. class CurrentUserBlockListener : public firebase::auth::AuthStateListener { public: explicit CurrentUserBlockListener() : semaphore_(0) {} diff --git a/auth/src/desktop/auth_providers/federated_auth_provider.cc b/auth/src/desktop/auth_providers/federated_auth_provider.cc index 94087abeb4..22239b75d2 100644 --- a/auth/src/desktop/auth_providers/federated_auth_provider.cc +++ b/auth/src/desktop/auth_providers/federated_auth_provider.cc @@ -107,8 +107,8 @@ Future FederatedOAuthProvider::Reauthenticate( AuthData* auth_data) { assert(auth_data); FIREBASE_ASSERT_RETURN(Future(), handler_); - Future future = - CreateAuthFuture(auth_data, kUserFn_ReauthenticateWithProvider_DEPRECATED); + Future future = CreateAuthFuture( + auth_data, kUserFn_ReauthenticateWithProvider_DEPRECATED); if (future.status() == kFutureStatusPending) { AuthCompletionHandle* auth_completion_handle = new AuthCompletionHandle( SafeFutureHandle(future.GetHandle()), auth_data); diff --git a/auth/src/desktop/authentication_result.cc b/auth/src/desktop/authentication_result.cc index f28798744b..c0ef5996e8 100644 --- a/auth/src/desktop/authentication_result.cc +++ b/auth/src/desktop/authentication_result.cc @@ -45,7 +45,8 @@ SignInResult AuthenticationResult::SetAsCurrentUser( // Save the previous user state to be able to check whether listeners should // be notified later on. UserData previous_user; - // Don't call Auth::current_user_DEPRECATED() to avoid locking the mutex twice. + // Don't call Auth::current_user_DEPRECATED() to avoid locking the mutex + // twice. User* api_user_to_return = nullptr; { UserView::Writer writer = diff --git a/auth/src/desktop/user_desktop.cc b/auth/src/desktop/user_desktop.cc index 0f5a100598..742875103b 100644 --- a/auth/src/desktop/user_desktop.cc +++ b/auth/src/desktop/user_desktop.cc @@ -105,9 +105,9 @@ GetTokenResult GetTokenIfFresh(const UserView::Reader& user, return GetTokenResult(kAuthErrorFailure); } -// Makes sure that calling auth->current_user_DEPRECATED()->id_token() will result in -// a token that is good for at least 5 minutes. Will fetch a new token from the -// backend if necessary. +// Makes sure that calling auth->current_user_DEPRECATED()->id_token() will +// result in a token that is good for at least 5 minutes. Will fetch a new token +// from the backend if necessary. // // If force_refresh is given, then a new token will be fetched without checking // the current token at all. @@ -840,8 +840,10 @@ Future User::Unlink_DEPRECATED(const char* const provider) { PerformSetAccountInfoFlow); } -Future User::LinkWithCredential_DEPRECATED(const Credential& credential) { - Promise promise(&auth_data_->future_impl, kUserFn_LinkWithCredential_DEPRECATED); +Future User::LinkWithCredential_DEPRECATED( + const Credential& credential) { + Promise promise(&auth_data_->future_impl, + kUserFn_LinkWithCredential_DEPRECATED); return DoLinkCredential(promise, auth_data_, credential.provider(), credential.impl_); } @@ -860,7 +862,8 @@ Future User::LinkWithProvider_DEPRECATED( // TODO(b/139363200) // return provider->Link(auth_data_); SafeFutureHandle handle = - auth_data_->future_impl.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED); + auth_data_->future_impl.SafeAlloc( + kUserFn_LinkWithProvider_DEPRECATED); auth_data_->future_impl.CompleteWithResult( handle, kAuthErrorUnimplemented, "Operation is not supported on non-mobile systems.", @@ -876,8 +879,9 @@ Future User::Reauthenticate(const Credential& credential) { Future User::ReauthenticateAndRetrieveData_DEPRECATED( const Credential& credential) { - Promise promise(&auth_data_->future_impl, - kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); + Promise promise( + &auth_data_->future_impl, + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); return DoReauthenticate(promise, auth_data_, credential.provider(), credential.impl_); } @@ -954,7 +958,8 @@ std::string User::provider_id() const { // Not implemented -Future User::UpdatePhoneNumberCredential_DEPRECATED(const Credential& credential) { +Future User::UpdatePhoneNumberCredential_DEPRECATED( + const Credential& credential) { Promise promise(&auth_data_->future_impl, kUserFn_UpdatePhoneNumberCredential_DEPRECATED); if (!ValidateCurrentUser(&promise, auth_data_)) { diff --git a/auth/src/include/firebase/auth.h b/auth/src/include/firebase/auth.h index 2733aa3aa9..dd5727d09e 100644 --- a/auth/src/include/firebase/auth.h +++ b/auth/src/include/firebase/auth.h @@ -240,32 +240,39 @@ class Auth { /// Get results of the most recent call to @ref FetchProvidersForEmail. Future FetchProvidersForEmailLastResult() const; - /// @deprecated This is a deprecated method. Please use @SignInWithCustomToken instead. + /// @deprecated This is a deprecated method. Please use @SignInWithCustomToken + /// instead. /// /// Asynchronously logs into Firebase with the given Auth token. /// /// An error is returned, if the token is invalid, expired or otherwise /// not accepted by the server. - FIREBASE_DEPRECATED Future SignInWithCustomToken_DEPRECATED(const char* token); + FIREBASE_DEPRECATED Future SignInWithCustomToken_DEPRECATED( + const char* token); /// @deprecated /// /// Get results of the most recent call to @ref SignInWithCustomToken. - FIREBASE_DEPRECATED Future SignInWithCustomTokenLastResult_DEPRECATED() const; + FIREBASE_DEPRECATED Future SignInWithCustomTokenLastResult_DEPRECATED() + const; /// @deprecated This is a deprecated method. Please use @SignInWithCredential /// instead. /// /// Convenience method for @ref SignInAndRetrieveDataWithCredential that /// doesn't return additional identity provider data. - FIREBASE_DEPRECATED Future SignInWithCredential_DEPRECATED(const Credential& credential); + FIREBASE_DEPRECATED Future SignInWithCredential_DEPRECATED( + const Credential& credential); /// @deprecated /// - /// Get results of the most recent call to @ref SignInWithCredential_DEPRECATED. - FIREBASE_DEPRECATED Future SignInWithCredentialLastResult_DEPRECATED() const; + /// Get results of the most recent call to @ref + /// SignInWithCredential_DEPRECATED. + FIREBASE_DEPRECATED Future SignInWithCredentialLastResult_DEPRECATED() + const; - /// @deprecated This is a deprecated method. Please use @SignInWithProvider instead. + /// @deprecated This is a deprecated method. Please use @SignInWithProvider + /// instead. /// /// Sign-in a user authenticated via a federated auth provider. /// @@ -277,9 +284,11 @@ class Auth { /// @note: This operation is supported only on iOS, tvOS and Android /// platforms. On other platforms this method will return a Future with a /// preset error code: kAuthErrorUnimplemented. - FIREBASE_DEPRECATED Future SignInWithProvider_DEPRECATED(FederatedAuthProvider* provider); + FIREBASE_DEPRECATED Future SignInWithProvider_DEPRECATED( + FederatedAuthProvider* provider); - /// @deprecated This is a deprecated method. Please use @SignInAndRetrieveDataWithCredential instead. + /// @deprecated This is a deprecated method. Please use + /// @SignInAndRetrieveDataWithCredential instead. /// /// Asynchronously logs into Firebase with the given credentials. /// @@ -292,14 +301,15 @@ class Auth { /// /// An error is returned if the token is invalid, expired, or otherwise not /// accepted by the server. - FIREBASE_DEPRECATED Future SignInAndRetrieveDataWithCredential_DEPRECATED( - const Credential& credential); + FIREBASE_DEPRECATED Future + SignInAndRetrieveDataWithCredential_DEPRECATED(const Credential& credential); /// @deprecated /// /// Get results of the most recent call to /// @ref SignInAndRetrieveDataWithCredential_DEPRECATED. - FIREBASE_DEPRECATED Future SignInAndRetrieveDataWithCredentialLastResult_DEPRECATED() const; + FIREBASE_DEPRECATED Future + SignInAndRetrieveDataWithCredentialLastResult_DEPRECATED() const; /// @deprecated This is a deprecated method. Please use @SignInAnonymously /// instead. @@ -362,34 +372,36 @@ class Auth { /// Get results of the most recent call to @ref SignInAnonymously_DEPRECATED. Future SignInAnonymouslyLastResult_DEPRECATED() const; - /// @deprecated This is a deprecated method. Please use @SignInWithEmailAndPassword - /// instead. + /// @deprecated This is a deprecated method. Please use + /// @SignInWithEmailAndPassword instead. /// /// Signs in using provided email address and password. /// An error is returned if the password is wrong or otherwise not accepted /// by the server. - FIREBASE_DEPRECATED Future SignInWithEmailAndPassword_DEPRECATED(const char* email, - const char* password); + FIREBASE_DEPRECATED Future SignInWithEmailAndPassword_DEPRECATED( + const char* email, const char* password); /// @deprecated /// - /// Get results of the most recent call to @ref SignInWithEmailAndPassword_DEPRECATED. + /// Get results of the most recent call to @ref + /// SignInWithEmailAndPassword_DEPRECATED. Future SignInWithEmailAndPasswordLastResult_DEPRECATED() const; - /// @deprecated This is a deprecated method. Please use @CreateUserWithEmailAndPassword - /// instead. + /// @deprecated This is a deprecated method. Please use + /// @CreateUserWithEmailAndPassword instead. /// /// Creates, and on success, logs in a user with the given email address /// and password. /// /// An error is returned when account creation is unsuccessful /// (due to another existing account, invalid password, etc.). - FIREBASE_DEPRECATED Future CreateUserWithEmailAndPassword_DEPRECATED(const char* email, - const char* password); + FIREBASE_DEPRECATED Future CreateUserWithEmailAndPassword_DEPRECATED( + const char* email, const char* password); /// Get results of the most recent call to /// @ref CreateUserWithEmailAndPassword_DEPRECATED. - FIREBASE_DEPRECATED Future CreateUserWithEmailAndPasswordLastResult_DEPRECATED() const; + FIREBASE_DEPRECATED Future + CreateUserWithEmailAndPasswordLastResult_DEPRECATED() const; /// Removes any existing authentication credentials from this client. /// This function always succeeds. @@ -578,9 +590,9 @@ class Auth { void* out_future); // Provides access to the current user's uid, equivalent to calling - // this->current_user_DEPRECATED()->uid(). Returns the current user's uid or an empty - // string, if there isn't one. The out pointer is expected to point to an - // instance of std::string. + // this->current_user_DEPRECATED()->uid(). Returns the current user's uid or + // an empty string, if there isn't one. The out pointer is expected to point + // to an instance of std::string. static bool GetCurrentUserUidForRegistry(App* app, void* /*unused*/, void* out); diff --git a/auth/src/include/firebase/auth/user.h b/auth/src/include/firebase/auth/user.h index 44949a4c20..ce3b4b6340 100644 --- a/auth/src/include/firebase/auth/user.h +++ b/auth/src/include/firebase/auth/user.h @@ -253,7 +253,7 @@ class User : public UserInfoInterface { /// Get results of the most recent call to @ref Reauthenticate. Future ReauthenticateLastResult() const; - /// @deprecated This is a deprecated method. Please use + /// @deprecated This is a deprecated method. Please use /// @ref ReauthenticateAndRetrieveData(const Credential&) instead. /// /// Reauthenticate using a credential. @@ -282,15 +282,16 @@ class User : public UserInfoInterface { /// or if sign-in with that credential failed. /// @note: The current user may be signed out if this operation fails on /// Android and desktop platforms. - FIREBASE_DEPRECATED Future ReauthenticateAndRetrieveData_DEPRECATED( - const Credential& credential); + FIREBASE_DEPRECATED Future + ReauthenticateAndRetrieveData_DEPRECATED(const Credential& credential); /// @deprecated /// /// Get results of the most recent call to @ref ReauthenticateAndRetrieveData. - FIREBASE_DEPRECATED Future ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const; + FIREBASE_DEPRECATED Future + ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const; - /// @deprecated This is a deprecated method. Please use + /// @deprecated This is a deprecated method. Please use /// @ref ReauthenticateWithProvider(FederatedAuthProvider*) instead. /// /// @brief Re-authenticates the user with a federated auth provider. @@ -317,17 +318,19 @@ class User : public UserInfoInterface { /// Get results of the most recent call to @ref UpdateUserProfile. Future UpdateUserProfileLastResult() const; - /// @deprecated This is a deprecated method. Please use + /// @deprecated This is a deprecated method. Please use /// @ref LinkWithCredential(const Credential&) instead. /// /// Convenience function for @ref ReauthenticateAndRetrieveData that discards /// the returned @ref AdditionalUserInfo in @ref SignInResult. - FIREBASE_DEPRECATED Future LinkWithCredential_DEPRECATED(const Credential& credential); + FIREBASE_DEPRECATED Future LinkWithCredential_DEPRECATED( + const Credential& credential); /// @deprecated /// /// Get results of the most recent call to @ref LinkWithCredential_DEPRECATED. - FIREBASE_DEPRECATED Future LinkWithCredentialLastResult_DEPRECATED() const; + FIREBASE_DEPRECATED Future LinkWithCredentialLastResult_DEPRECATED() + const; /// Links the user with the given 3rd party credentials. /// @@ -347,7 +350,7 @@ class User : public UserInfoInterface { /// @ref LinkAndRetrieveDataWithCredential. Future LinkAndRetrieveDataWithCredentialLastResult() const; - /// @deprecated This is a deprecated method. Please use + /// @deprecated This is a deprecated method. Please use /// @ref LinkWithProvider(FederatedAuthProvider*) instead. /// /// Links this user with a federated auth provider. @@ -360,9 +363,11 @@ class User : public UserInfoInterface { /// @note: This operation is supported only on iOS, tvOS and Android /// platforms. On other platforms this method will return a Future with a /// preset error code: kAuthErrorUnimplemented. - Future LinkWithProvider_DEPRECATED(FederatedAuthProvider* provider) const; + Future LinkWithProvider_DEPRECATED( + FederatedAuthProvider* provider) const; - /// @deprecated This is a deprecated method. Please use @ref Unlink(const char*) instead. + /// @deprecated This is a deprecated method. Please use @ref Unlink(const + /// char*) instead. /// /// Unlinks the current user from the provider specified. /// Status will be an error if the user is not linked to the given provider. @@ -373,19 +378,21 @@ class User : public UserInfoInterface { /// Get results of the most recent call to @ref Unlink. Future UnlinkLastResult_DEPRECATED() const; - /// @deprecated This is a deprecated method. Please use + /// @deprecated This is a deprecated method. Please use /// @ref UpdatePhoneNumberCredential(const PhoneAuthCredential&) instead. /// /// Updates the currently linked phone number on the user. /// This is useful when a user wants to change their phone number. It is a - /// shortcut to calling Unlink_DEPRECATED(phone_credential.provider().c_str()) and then - /// LinkWithCredential_DEPRECATED(phone_credential). - /// `credential` must have been created with @ref PhoneAuthProvider. - Future UpdatePhoneNumberCredential_DEPRECATED(const Credential& credential); + /// shortcut to calling Unlink_DEPRECATED(phone_credential.provider().c_str()) + /// and then LinkWithCredential_DEPRECATED(phone_credential). `credential` + /// must have been created with @ref PhoneAuthProvider. + Future UpdatePhoneNumberCredential_DEPRECATED( + const Credential& credential); /// @deprecated //// - /// Get results of the most recent call to @ref UpdatePhoneNumberCredential_DEPRECATED. + /// Get results of the most recent call to @ref + /// UpdatePhoneNumberCredential_DEPRECATED. Future UpdatePhoneNumberCredentialLastResult_DEPRECATED() const; /// Refreshes the data for this user. diff --git a/auth/src/ios/auth_ios.mm b/auth/src/ios/auth_ios.mm index 8a7bacd289..c004c595ff 100644 --- a/auth/src/ios/auth_ios.mm +++ b/auth/src/ios/auth_ios.mm @@ -386,10 +386,11 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu return MakeFuture(&futures, handle); } -Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED(const Credential &credential) { +Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( + const Credential &credential) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED, SignInResult()); + const auto handle = futures.SafeAlloc( + kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED, SignInResult()); [AuthImpl(auth_data_) signInWithCredential:CredentialFromImpl(credential.impl_) @@ -407,7 +408,8 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SignInAnonymously_DEPRECATED() { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = auth_data_->future_impl.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED, nullptr); + const auto handle = + auth_data_->future_impl.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED, nullptr); [AuthImpl(auth_data_) signInAnonymouslyWithCompletion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { @@ -417,9 +419,11 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu return MakeFuture(&futures, handle); } -Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { +Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char *email, + const char *password) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED, nullptr); + const auto handle = + futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED, nullptr); if (!email || strlen(email) == 0) { futures.Complete(handle, kAuthErrorMissingEmail, "Empty email is not allowed."); } else if (!password || strlen(password) == 0) { @@ -435,9 +439,11 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu return MakeFuture(&futures, handle); } -Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { +Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char *email, + const char *password) { ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED, nullptr); + const auto handle = + futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED, nullptr); if (!email || strlen(email) == 0) { futures.Complete(handle, kAuthErrorMissingEmail, "Empty email is not allowed."); } else if (!password || strlen(password) == 0) { diff --git a/auth/src/ios/credential_ios.mm b/auth/src/ios/credential_ios.mm index 86d1d860c0..e256956f34 100644 --- a/auth/src/ios/credential_ios.mm +++ b/auth/src/ios/credential_ios.mm @@ -454,7 +454,8 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl Future FederatedOAuthProvider::SignIn(AuthData* auth_data) { assert(auth_data); ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithProvider_DEPRECATED, SignInResult()); + const auto handle = + futures.SafeAlloc(kAuthFn_SignInWithProvider_DEPRECATED, SignInResult()); FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) auth:AuthImpl(auth_data)]; @@ -480,7 +481,8 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl Future FederatedOAuthProvider::Link(AuthData* auth_data) { assert(auth_data); ReferenceCountedFutureImpl& futures = auth_data->future_impl; - auto handle = futures.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + auto handle = + futures.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) @@ -514,7 +516,8 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl Future FederatedOAuthProvider::Reauthenticate(AuthData* auth_data) { assert(auth_data); ReferenceCountedFutureImpl& futures = auth_data->future_impl; - auto handle = futures.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + auto handle = + futures.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) diff --git a/auth/src/ios/user_ios.mm b/auth/src/ios/user_ios.mm index c34b987683..56d507ab29 100644 --- a/auth/src/ios/user_ios.mm +++ b/auth/src/ios/user_ios.mm @@ -282,7 +282,8 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { return MakeFuture(&futures, handle); } -Future User::ReauthenticateWithProvider_DEPRECATED(FederatedAuthProvider *provider) const { +Future User::ReauthenticateWithProvider_DEPRECATED( + FederatedAuthProvider *provider) const { FIREBASE_ASSERT_RETURN(Future(), provider); return provider->Reauthenticate(auth_data_); } diff --git a/auth/tests/auth_test.cc b/auth/tests/auth_test.cc index 5d88957ca9..7a156781b1 100644 --- a/auth/tests/auth_test.cc +++ b/auth/tests/auth_test.cc @@ -231,7 +231,8 @@ TEST_F(AuthTest, TestSignInWithCustomTokenSucceeded) { " ]" "}"); MakeAuth(); - Future result = firebase_auth_->SignInWithCustomToken_DEPRECATED("its-a-token"); + Future result = + firebase_auth_->SignInWithCustomToken_DEPRECATED("its-a-token"); Verify(kAuthErrorNone, result); } @@ -260,7 +261,8 @@ TEST_F(AuthTest, TestSignInWithCredentialSucceeded) { "}"); MakeAuth(); Credential credential = EmailAuthProvider::GetCredential("abc@g.com", "abc"); - Future result = firebase_auth_->SignInWithCredential_DEPRECATED(credential); + Future result = + firebase_auth_->SignInWithCredential_DEPRECATED(credential); Verify(kAuthErrorNone, result); } @@ -316,8 +318,8 @@ TEST_F(AuthTest, TestSignInWithEmailAndPasswordSucceeded) { " ]" "}"); MakeAuth(); - Future result = - firebase_auth_->SignInWithEmailAndPassword_DEPRECATED("abc@xyz.com", "password"); + Future result = firebase_auth_->SignInWithEmailAndPassword_DEPRECATED( + "abc@xyz.com", "password"); Verify(kAuthErrorNone, result); } @@ -346,7 +348,8 @@ TEST_F(AuthTest, TestCreateUserWithEmailAndPasswordSucceeded) { "}"); MakeAuth(); Future result = - firebase_auth_->CreateUserWithEmailAndPassword_DEPRECATED("abc@xyz.com", "password"); + firebase_auth_->CreateUserWithEmailAndPassword_DEPRECATED("abc@xyz.com", + "password"); Verify(kAuthErrorNone, result); } @@ -375,7 +378,8 @@ TEST_F(AuthTest, TestSignInWithCustomTokenFailed) { " ]" "}"); MakeAuth(); - Future result = firebase_auth_->SignInWithCustomToken_DEPRECATED("its-a-token"); + Future result = + firebase_auth_->SignInWithCustomToken_DEPRECATED("its-a-token"); Verify(kAuthErrorInvalidCustomToken, result); } @@ -399,7 +403,8 @@ TEST_F(AuthTest, TestSignInWithCredentialFailed) { "}"); MakeAuth(); Credential credential = EmailAuthProvider::GetCredential("abc@g.com", "abc"); - Future result = firebase_auth_->SignInWithCredential_DEPRECATED(credential); + Future result = + firebase_auth_->SignInWithCredential_DEPRECATED(credential); Verify(kAuthErrorInvalidEmail, result); } @@ -445,8 +450,8 @@ TEST_F(AuthTest, TestSignInWithEmailAndPasswordFailed) { " ]" "}"); MakeAuth(); - Future result = - firebase_auth_->SignInWithEmailAndPassword_DEPRECATED("abc@xyz.com", "password"); + Future result = firebase_auth_->SignInWithEmailAndPassword_DEPRECATED( + "abc@xyz.com", "password"); Verify(kAuthErrorWrongPassword, result); } @@ -470,7 +475,8 @@ TEST_F(AuthTest, TestCreateUserWithEmailAndPasswordFailed) { "}"); MakeAuth(); Future result = - firebase_auth_->CreateUserWithEmailAndPassword_DEPRECATED("abc@xyz.com", "password"); + firebase_auth_->CreateUserWithEmailAndPassword_DEPRECATED("abc@xyz.com", + "password"); Verify(kAuthErrorEmailAlreadyInUse, result); } diff --git a/auth/tests/desktop/auth_desktop_test.cc b/auth/tests/desktop/auth_desktop_test.cc index 5052182269..374fae0d34 100644 --- a/auth/tests/desktop/auth_desktop_test.cc +++ b/auth/tests/desktop/auth_desktop_test.cc @@ -271,7 +271,8 @@ class AuthDesktopTest : public ::testing::Test { InitializeSignInWithProviderFakes(CreateGetAccountInfoFake()); provider->SetProviderData(GetFakeOAuthProviderData()); provider->SetAuthHandler(handler); - Future future = firebase_auth_->SignInWithProvider_DEPRECATED(provider); + Future future = + firebase_auth_->SignInWithProvider_DEPRECATED(provider); if (trigger_sign_in) { handler->TriggerSignInComplete(); } @@ -287,7 +288,8 @@ class AuthDesktopTest : public ::testing::Test { TEST_F(AuthDesktopTest, TestSignInWithProviderReturnsUnsupportedError) { FederatedOAuthProvider provider; - Future future = firebase_auth_->SignInWithProvider_DEPRECATED(&provider); + Future future = + firebase_auth_->SignInWithProvider_DEPRECATED(&provider); EXPECT_EQ(future.result()->user, nullptr); EXPECT_EQ(future.error(), kAuthErrorUnimplemented); EXPECT_EQ(std::string(future.error_message()), @@ -300,7 +302,8 @@ TEST_F(AuthDesktopTest, OAuthProviderTestHandler handler(/*extra_integrity_checks_=*/true); InitializeSuccessfulSignInWithProviderFlow(&provider, &handler); - Future future = firebase_auth_->SignInWithProvider_DEPRECATED(&provider); + Future future = + firebase_auth_->SignInWithProvider_DEPRECATED(&provider); handler.TriggerSignInComplete(); SignInResult sign_in_result = WaitForFuture(future); } @@ -316,9 +319,11 @@ TEST_F(AuthDesktopTest, OAuthProviderTestHandler handler2; provider2.SetAuthHandler(&handler2); - Future future1 = firebase_auth_->SignInWithProvider_DEPRECATED(&provider1); + Future future1 = + firebase_auth_->SignInWithProvider_DEPRECATED(&provider1); EXPECT_EQ(future1.status(), kFutureStatusPending); - Future future2 = firebase_auth_->SignInWithProvider_DEPRECATED(&provider2); + Future future2 = + firebase_auth_->SignInWithProvider_DEPRECATED(&provider2); VerifySignInResult(future2, kAuthErrorFederatedProviderAreadyInUse); handler1.TriggerSignInComplete(); const SignInResult sign_in_result = WaitForFuture(future1); @@ -499,8 +504,8 @@ TEST_F(AuthDesktopTest, CompleteSignInWithFailedResponse) { auth_state_listener.ExpectChanges(1); // Call the function and verify results. - const User* const user = - WaitForFuture(firebase_auth_->SignInAnonymously_DEPRECATED(), kAuthErrorFailure); + const User* const user = WaitForFuture( + firebase_auth_->SignInAnonymously_DEPRECATED(), kAuthErrorFailure); EXPECT_EQ(nullptr, user); } @@ -525,8 +530,8 @@ TEST_F(AuthDesktopTest, CompleteSignInWithGetAccountInfoFailure) { auth_state_listener.ExpectChanges(1); // Call the function and verify results. - const User* const user = - WaitForFuture(firebase_auth_->SignInAnonymously_DEPRECATED(), kAuthErrorFailure); + const User* const user = WaitForFuture( + firebase_auth_->SignInAnonymously_DEPRECATED(), kAuthErrorFailure); EXPECT_EQ(nullptr, user); } @@ -556,7 +561,8 @@ TEST_F(AuthDesktopTest, TestSignInAnonymously) { id_token_listener.ExpectChanges(2); auth_state_listener.ExpectChanges(2); - const User* const user = WaitForFuture(firebase_auth_->SignInAnonymously_DEPRECATED()); + const User* const user = + WaitForFuture(firebase_auth_->SignInAnonymously_DEPRECATED()); EXPECT_TRUE(user->is_anonymous()); EXPECT_EQ("localid123", user->uid()); EXPECT_EQ("", user->email()); @@ -585,8 +591,9 @@ TEST_F(AuthDesktopTest, TestSignInWithEmailAndPassword) { auth_state_listener.ExpectChanges(2); // Call the function and verify results. - const Future future = firebase_auth_->SignInWithEmailAndPassword_DEPRECATED( - "testsignin@example.com", "testsignin"); + const Future future = + firebase_auth_->SignInWithEmailAndPassword_DEPRECATED( + "testsignin@example.com", "testsignin"); const User* const user = WaitForFuture(future); EXPECT_FALSE(user->is_anonymous()); VerifyUser(*user); @@ -620,8 +627,9 @@ TEST_F(AuthDesktopTest, TestCreateUserWithEmailAndPassword) { id_token_listener.ExpectChanges(2); auth_state_listener.ExpectChanges(2); - const Future future = firebase_auth_->CreateUserWithEmailAndPassword_DEPRECATED( - "testsignin@example.com", "testsignin"); + const Future future = + firebase_auth_->CreateUserWithEmailAndPassword_DEPRECATED( + "testsignin@example.com", "testsignin"); const User* const user = WaitForFuture(future); EXPECT_FALSE(user->is_anonymous()); VerifyUser(*user); @@ -643,8 +651,8 @@ TEST_F(AuthDesktopTest, TestSignInWithCustomToken) { id_token_listener.ExpectChanges(2); auth_state_listener.ExpectChanges(2); - const User* const user = - WaitForFuture(firebase_auth_->SignInWithCustomToken_DEPRECATED("fake_custom_token")); + const User* const user = WaitForFuture( + firebase_auth_->SignInWithCustomToken_DEPRECATED("fake_custom_token")); EXPECT_FALSE(user->is_anonymous()); VerifyUser(*user); } @@ -659,8 +667,8 @@ TEST_F(AuthDesktopTest, TestSignInWithCredential_GoogleIdToken) { const Credential credential = GoogleAuthProvider::GetCredential("fake_id_token", ""); - const User* const user = - WaitForFuture(firebase_auth_->SignInWithCredential_DEPRECATED(credential)); + const User* const user = WaitForFuture( + firebase_auth_->SignInWithCredential_DEPRECATED(credential)); EXPECT_FALSE(user->is_anonymous()); VerifyUser(*user); } @@ -673,8 +681,8 @@ TEST_F(AuthDesktopTest, TestSignInWithCredential_GoogleAccessToken) { const Credential credential = GoogleAuthProvider::GetCredential("", "fake_access_token"); - const User* const user = - WaitForFuture(firebase_auth_->SignInWithCredential_DEPRECATED(credential)); + const User* const user = WaitForFuture( + firebase_auth_->SignInWithCredential_DEPRECATED(credential)); EXPECT_FALSE(user->is_anonymous()); VerifyUser(*user); } @@ -691,8 +699,9 @@ TEST_F(AuthDesktopTest, const Credential credential = GoogleAuthProvider::GetCredential("", "fake_access_token"); - const User* const user = WaitForFuture( - firebase_auth_->SignInWithCredential_DEPRECATED(credential), kAuthErrorFailure); + const User* const user = + WaitForFuture(firebase_auth_->SignInWithCredential_DEPRECATED(credential), + kAuthErrorFailure); EXPECT_EQ(nullptr, user); } @@ -709,8 +718,9 @@ TEST_F(AuthDesktopTest, const Credential credential = GoogleAuthProvider::GetCredential("", "fake_access_token"); - const User* const user = WaitForFuture( - firebase_auth_->SignInWithCredential_DEPRECATED(credential), kAuthErrorFailure); + const User* const user = + WaitForFuture(firebase_auth_->SignInWithCredential_DEPRECATED(credential), + kAuthErrorFailure); EXPECT_EQ(nullptr, user); } @@ -744,7 +754,8 @@ TEST_F(AuthDesktopTest, TestSignInAndRetrieveDataWithCredential_GitHub) { const Credential credential = GitHubAuthProvider::GetCredential("fake_access_token"); const SignInResult sign_in_result = WaitForFuture( - firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED(credential)); + firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED( + credential)); EXPECT_FALSE(sign_in_result.user->is_anonymous()); VerifyUser(*sign_in_result.user); @@ -773,7 +784,8 @@ TEST_F(AuthDesktopTest, TestSignInAndRetrieveDataWithCredential_Twitter) { const Credential credential = TwitterAuthProvider::GetCredential( "fake_access_token", "fake_oauth_token"); const SignInResult sign_in_result = WaitForFuture( - firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED(credential)); + firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED( + credential)); EXPECT_FALSE(sign_in_result.user->is_anonymous()); VerifyUser(*sign_in_result.user); @@ -793,7 +805,8 @@ TEST_F(AuthDesktopTest, const Credential credential = TwitterAuthProvider::GetCredential( "fake_access_token", "fake_oauth_token"); const SignInResult sign_in_result = WaitForFuture( - firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED(credential)); + firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED( + credential)); EXPECT_FALSE(sign_in_result.user->is_anonymous()); VerifyUser(*sign_in_result.user); @@ -816,7 +829,8 @@ TEST_F(AuthDesktopTest, const Credential credential = TwitterAuthProvider::GetCredential( "fake_access_token", "fake_oauth_token"); const SignInResult sign_in_result = WaitForFuture( - firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED(credential)); + firebase_auth_->SignInAndRetrieveDataWithCredential_DEPRECATED( + credential)); EXPECT_FALSE(sign_in_result.user->is_anonymous()); VerifyUser(*sign_in_result.user); diff --git a/auth/tests/desktop/user_desktop_test.cc b/auth/tests/desktop/user_desktop_test.cc index 1dcba4cee8..b42260081e 100644 --- a/auth/tests/desktop/user_desktop_test.cc +++ b/auth/tests/desktop/user_desktop_test.cc @@ -311,7 +311,8 @@ class UserDesktopTest : public ::testing::Test { FederatedOAuthProvider* provider, OAuthProviderTestHandler* handler, bool trigger_link) { InitializeSuccessfulAuthenticateWithProviderFlow(provider, handler); - Future future = firebase_user_->LinkWithProvider_DEPRECATED(provider); + Future future = + firebase_user_->LinkWithProvider_DEPRECATED(provider); if (trigger_link) { handler->TriggerLinkComplete(); } @@ -342,9 +343,12 @@ class UserDesktopTest : public ::testing::Test { // Test that metadata is correctly being populated and exposed TEST_F(UserDesktopTest, TestAccountMetadata) { - EXPECT_EQ(123, - firebase_auth_->current_user_DEPRECATED()->metadata().last_sign_in_timestamp); - EXPECT_EQ(456, firebase_auth_->current_user_DEPRECATED()->metadata().creation_timestamp); + EXPECT_EQ(123, firebase_auth_->current_user_DEPRECATED() + ->metadata() + .last_sign_in_timestamp); + EXPECT_EQ( + 456, + firebase_auth_->current_user_DEPRECATED()->metadata().creation_timestamp); } TEST_F(UserDesktopTest, TestGetToken) { @@ -624,11 +628,13 @@ TEST_F(UserDesktopTest, TestLinkWithCredential_ChecksAlreadyLinkedProviders) { const Credential google_credential = GoogleAuthProvider::GetCredential("fake_id_token", ""); - WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(google_credential)); + WaitForFuture( + firebase_user_->LinkWithCredential_DEPRECATED(google_credential)); // The same provider shouldn't be linked twice. - WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(google_credential), - kAuthErrorProviderAlreadyLinked); + WaitForFuture( + firebase_user_->LinkWithCredential_DEPRECATED(google_credential), + kAuthErrorProviderAlreadyLinked); id_token_listener.VerifyAndReset(); auth_state_listener.VerifyAndReset(); @@ -662,14 +668,17 @@ TEST_F(UserDesktopTest, TestLinkWithCredential_ChecksAlreadyLinkedProviders) { // Should be able to link a different provider. const Credential facebook_credential = FacebookAuthProvider::GetCredential("fake_access_token"); - WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(facebook_credential)); + WaitForFuture( + firebase_user_->LinkWithCredential_DEPRECATED(facebook_credential)); // The same provider shouldn't be linked twice. - WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(facebook_credential), - kAuthErrorProviderAlreadyLinked); + WaitForFuture( + firebase_user_->LinkWithCredential_DEPRECATED(facebook_credential), + kAuthErrorProviderAlreadyLinked); // Check that the previously linked provider wasn't overridden. - WaitForFuture(firebase_user_->LinkWithCredential_DEPRECATED(google_credential), - kAuthErrorProviderAlreadyLinked); + WaitForFuture( + firebase_user_->LinkWithCredential_DEPRECATED(google_credential), + kAuthErrorProviderAlreadyLinked); } TEST_F(UserDesktopTest, TestLinkWithCredentialAndRetrieveData) { @@ -726,8 +735,8 @@ TEST_F(UserDesktopTest, TestReauthenticateAndRetrieveData) { const Credential credential = GoogleAuthProvider::GetCredential("fake_id_token", ""); - const SignInResult sign_in_result = - WaitForFuture(firebase_user_->ReauthenticateAndRetrieveData_DEPRECATED(credential)); + const SignInResult sign_in_result = WaitForFuture( + firebase_user_->ReauthenticateAndRetrieveData_DEPRECATED(credential)); EXPECT_FALSE(sign_in_result.user->is_anonymous()); VerifyUser(*sign_in_result.user); } @@ -896,7 +905,8 @@ TEST_F(UserDesktopTest, TestRaceCondition_SetAccountInfoAndSignOut) { // LinkWithProvider tests. TEST_F(UserDesktopTest, TestLinkWithProviderReturnsUnsupportedError) { FederatedOAuthProvider provider; - Future future = firebase_user_->LinkWithProvider_DEPRECATED(&provider); + Future future = + firebase_user_->LinkWithProvider_DEPRECATED(&provider); EXPECT_EQ(future.result()->user, nullptr); EXPECT_EQ(future.error(), kAuthErrorUnimplemented); EXPECT_EQ(std::string(future.error_message()), @@ -911,7 +921,8 @@ TEST_F(UserDesktopTest, test::OAuthProviderTestHandler handler(/*extra_integrity_checks_=*/true); InitializeSuccessfulAuthenticateWithProviderFlow(&provider, &handler); - Future future = firebase_user_->LinkWithProvider_DEPRECATED(&provider); + Future future = + firebase_user_->LinkWithProvider_DEPRECATED(&provider); handler.TriggerLinkComplete(); SignInResult sign_in_result = WaitForFuture(future); } @@ -927,9 +938,11 @@ TEST_F(UserDesktopTest, OAuthProviderTestHandler handler2; provider2.SetAuthHandler(&handler2); - Future future1 = firebase_user_->LinkWithProvider_DEPRECATED(&provider1); + Future future1 = + firebase_user_->LinkWithProvider_DEPRECATED(&provider1); EXPECT_EQ(future1.status(), kFutureStatusPending); - Future future2 = firebase_user_->LinkWithProvider_DEPRECATED(&provider2); + Future future2 = + firebase_user_->LinkWithProvider_DEPRECATED(&provider2); VerifySignInResult(future2, kAuthErrorFederatedProviderAreadyInUse); handler1.TriggerLinkComplete(); const SignInResult sign_in_result = WaitForFuture(future1); diff --git a/auth/tests/user_test.cc b/auth/tests/user_test.cc index 21c9df13c5..cb25630126 100644 --- a/auth/tests/user_test.cc +++ b/auth/tests/user_test.cc @@ -368,8 +368,9 @@ TEST_F(UserTest, TestReauthenticateAndRetrieveData) { "}"; firebase::testing::cppsdk::ConfigSet(config.c_str()); - Future result = firebase_user_->ReauthenticateAndRetrieveData_DEPRECATED( - EmailAuthProvider::GetCredential("i@email.com", "pw")); + Future result = + firebase_user_->ReauthenticateAndRetrieveData_DEPRECATED( + EmailAuthProvider::GetCredential("i@email.com", "pw")); Verify(result); } #endif // !defined(__APPLE__) && !defined(FIREBASE_WAIT_ASYNC_IN_TEST) From 323d41d21047867e7b275f6e8c429c68c98597ad Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Sun, 12 Mar 2023 21:44:11 -0400 Subject: [PATCH 05/14] bundle identifer --- auth/integration_test/Info.plist | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/auth/integration_test/Info.plist b/auth/integration_test/Info.plist index d7acd29687..524550beb3 100644 --- a/auth/integration_test/Info.plist +++ b/auth/integration_test/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.google.FirebaseCppAuthTestApp.dev + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -22,10 +22,10 @@ CFBundleTypeRole Editor CFBundleURLName - com.google.FirebaseCppAuthTestApp.dev + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleURLSchemes - com.google.FirebaseCppAuthTestApp.dev + $(PRODUCT_BUNDLE_IDENTIFIER) @@ -35,7 +35,7 @@ google CFBundleURLSchemes - com.googleusercontent.apps.53101460582-aosfj1hlbc89719t6qfian100u6hehh8 + REPLACE_WITH_REVERSED_CLIENT_ID firebase-game-loop From b247244c7598aa4c11924d43fc57d52d397cc292 Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Mon, 13 Mar 2023 10:45:49 -0400 Subject: [PATCH 06/14] removed explicit from CurrentUserBlockListener constructor --- auth/src/desktop/auth_desktop.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/src/desktop/auth_desktop.cc b/auth/src/desktop/auth_desktop.cc index 2eb756443b..307c00a971 100644 --- a/auth/src/desktop/auth_desktop.cc +++ b/auth/src/desktop/auth_desktop.cc @@ -518,7 +518,7 @@ void Auth::SignOut() { // cache load is finished. class CurrentUserBlockListener : public firebase::auth::AuthStateListener { public: - explicit CurrentUserBlockListener() : semaphore_(0) {} + CurrentUserBlockListener() : semaphore_(0) {} ~CurrentUserBlockListener() override {} void OnAuthStateChanged(Auth* auth) override { semaphore_.Post(); } From c208b232a35e81aece231efedc5aa66a79ab0979 Mon Sep 17 00:00:00 2001 From: DellaBitta Date: Sun, 19 Mar 2023 17:47:00 -0400 Subject: [PATCH 07/14] iOS support for multiple User objects (#1242) Update auth internals to support returning Future object for the new API while also support returning Future objects for the deprecated API on iOS. Changes does not include the new Future methods. --- auth/integration_test/src/integration_test.cc | 24 +- auth/src/auth.cc | 1 - auth/src/common.cc | 58 ++ auth/src/common.h | 62 +- auth/src/data.h | 52 +- auth/src/desktop/user_desktop.h | 46 +- auth/src/include/firebase/auth.h | 16 +- auth/src/include/firebase/auth/credential.h | 2 + auth/src/include/firebase/auth/types.h | 3 + auth/src/include/firebase/auth/user.h | 70 +- auth/src/ios/auth_ios.mm | 78 +- auth/src/ios/common_ios.h | 136 ++- auth/src/ios/credential_ios.mm | 125 +-- auth/src/ios/user_ios.mm | 821 +++++++++++++----- auth/src/user.cc | 20 +- 15 files changed, 1141 insertions(+), 373 deletions(-) diff --git a/auth/integration_test/src/integration_test.cc b/auth/integration_test/src/integration_test.cc index d7d4abd443..3727bcab9d 100644 --- a/auth/integration_test/src/integration_test.cc +++ b/auth/integration_test/src/integration_test.cc @@ -162,7 +162,6 @@ void FirebaseAuthTest::Initialize() { ::firebase::ModuleInitializer initializer; initializer.Initialize(app_, &auth_, [](::firebase::App* app, void* target) { - LogDebug("Try to initialize Firebase Auth"); firebase::InitResult result; firebase::auth::Auth** auth_ptr = reinterpret_cast(target); @@ -176,8 +175,6 @@ void FirebaseAuthTest::Initialize() { ASSERT_EQ(initializer.InitializeLastResult().error(), 0) << initializer.InitializeLastResult().error_message(); - LogDebug("Successfully initialized Firebase Auth."); - initialized_ = true; } @@ -516,8 +513,9 @@ TEST_F(FirebaseAuthTest, TestLinkAnonymousUserWithEmailCredential) { firebase::auth::Credential credential = firebase::auth::EmailAuthProvider::GetCredential(email.c_str(), kTestPassword); - WaitForCompletion(user->LinkAndRetrieveDataWithCredential(credential), - "LinkAndRetrieveDataWithCredential"); + WaitForCompletion( + user->LinkAndRetrieveDataWithCredential_DEPRECATED(credential), + "LinkAndRetrieveDataWithCredential_DEPRECATED"); WaitForCompletion(user->Unlink_DEPRECATED(credential.provider().c_str()), "Unlink"); SignOut(); @@ -768,10 +766,12 @@ TEST_F(FirebaseAuthTest, TestAuthPersistenceWithEmailSignin) { // Save the old provider ID list so we can make sure it's the same once // it's loaded again. std::vector prev_provider_data_ids; - for (int i = 0; i < auth_->current_user_DEPRECATED()->provider_data().size(); + for (int i = 0; + i < auth_->current_user_DEPRECATED()->provider_data_DEPRECATED().size(); i++) { - prev_provider_data_ids.push_back( - auth_->current_user_DEPRECATED()->provider_data()[i]->provider_id()); + prev_provider_data_ids.push_back(auth_->current_user_DEPRECATED() + ->provider_data_DEPRECATED()[i] + ->provider_id()); } Terminate(); ProcessEvents(2000); @@ -782,10 +782,12 @@ TEST_F(FirebaseAuthTest, TestAuthPersistenceWithEmailSignin) { // Make sure the provider IDs are the same as they were before. EXPECT_EQ(auth_->current_user_DEPRECATED()->provider_id(), prev_provider_id); std::vector loaded_provider_data_ids; - for (int i = 0; i < auth_->current_user_DEPRECATED()->provider_data().size(); + for (int i = 0; + i < auth_->current_user_DEPRECATED()->provider_data_DEPRECATED().size(); i++) { - loaded_provider_data_ids.push_back( - auth_->current_user_DEPRECATED()->provider_data()[i]->provider_id()); + loaded_provider_data_ids.push_back(auth_->current_user_DEPRECATED() + ->provider_data_DEPRECATED()[i] + ->provider_id()); } EXPECT_TRUE(loaded_provider_data_ids == prev_provider_data_ids); diff --git a/auth/src/auth.cc b/auth/src/auth.cc index fe92cd421d..a7bd564e53 100644 --- a/auth/src/auth.cc +++ b/auth/src/auth.cc @@ -81,7 +81,6 @@ Auth* Auth::GetAuth(App* app, InitResult* init_result_out) { // Create a new Auth and initialize. Auth* auth = new Auth(app, auth_impl); - LogDebug("Creating Auth %p for App %p", auth, app); // Stick it in the global map so we remember it, and can delete it on // shutdown. diff --git a/auth/src/common.cc b/auth/src/common.cc index 70324d4831..510d1f82c0 100644 --- a/auth/src/common.cc +++ b/auth/src/common.cc @@ -21,6 +21,11 @@ namespace firebase { namespace auth { +const char* kUserNotInitializedErrorMessage = + "Operation attmpted on an invalid User object."; +const char* kPhoneAuthNotSupportedErrorMessage = + "Phone Auth is not supported on this platform."; + // static member variables const uint32_t PhoneAuthProvider::kMaxTimeoutMs = 3000; @@ -47,6 +52,59 @@ ReferenceCountedFutureImpl* GetCredentialFutureImpl() { return future_data->api(); } +void CompleteFuture(int error, const char* error_msg, + SafeFutureHandle handle, FutureData* future_data) { + if (future_data->future_impl.ValidFuture(handle)) { + future_data->future_impl.Complete(handle, error, error_msg); + } +} + +void CompleteFuture(int error, const char* error_msg, + SafeFutureHandle handle, + FutureData* future_data, const std::string& result) { + if (future_data->future_impl.ValidFuture(handle)) { + future_data->future_impl.CompleteWithResult(handle, error, error_msg, + result); + } +} + +void CompleteFuture(int error, const char* error_msg, + SafeFutureHandle handle, FutureData* future_data, + User* user) { + if (future_data->future_impl.ValidFuture(handle)) { + future_data->future_impl.CompleteWithResult(handle, error, error_msg, user); + } +} + +void CompleteFuture(int error, const char* error_msg, + SafeFutureHandle handle, + FutureData* future_data, SignInResult sign_in_result) { + if (future_data->future_impl.ValidFuture(handle)) { + future_data->future_impl.CompleteWithResult(handle, error, error_msg, + sign_in_result); + } +} + +// For calls that aren't asynchronous, we can create and complete at the +// same time. +Future CreateAndCompleteFuture(int fn_idx, int error, + const char* error_msg, + FutureData* future_data) { + SafeFutureHandle handle = CreateFuture(fn_idx, future_data); + CompleteFuture(error, error_msg, handle, future_data); + return MakeFuture(&future_data->future_impl, handle); +} + +Future CreateAndCompleteFuture(int fn_idx, int error, + const char* error_msg, + FutureData* future_data, + const std::string& result) { + SafeFutureHandle handle = + CreateFuture(fn_idx, future_data); + CompleteFuture(error, error_msg, handle, future_data, result); + return MakeFuture(&future_data->future_impl, handle); +} + void CleanupCredentialFutureImpl() { StaticFutureData::CleanupFutureDataForModule(&kCredentialFutureIdentifier); } diff --git a/auth/src/common.h b/auth/src/common.h index dc70768108..80674ab2bd 100644 --- a/auth/src/common.h +++ b/auth/src/common.h @@ -17,11 +17,18 @@ #ifndef FIREBASE_AUTH_SRC_COMMON_H_ #define FIREBASE_AUTH_SRC_COMMON_H_ +#include + #include "auth/src/data.h" namespace firebase { namespace auth { +// Error messages used for completing futures. These match the error codes in +// the AdErrorCode enumeration in the C++ API. +extern const char* kUserNotInitializedErrorMessage; +extern const char* kPhoneAuthNotSupportedErrorMessage; + // Enumeration for Credential API functions that return a Future. // This allows us to hold a Future for the most recent call to that API. enum CredentialApiFunction { @@ -30,6 +37,59 @@ enum CredentialApiFunction { kNumCredentialFunctions }; +// Hold backing data for returned Futures. +struct FutureData { + explicit FutureData(int num_functions_that_return_futures) + : future_impl(num_functions_that_return_futures) {} + + // Handle calls from Futures that the API returns. + ReferenceCountedFutureImpl future_impl; +}; + +template +struct FutureCallbackData { + FutureData* future_data; + SafeFutureHandle future_handle; +}; + +// Create a future and update the corresponding last result. +template +SafeFutureHandle CreateFuture(int fn_idx, FutureData* future_data) { + return future_data->future_impl.SafeAlloc(fn_idx); +} + +// Mark a Future as complete. +void CompleteFuture(int error, const char* error_msg, + SafeFutureHandle handle, FutureData* future_data); + +// Mark a Future as complete +void CompleteFuture(int error, const char* error_msg, + SafeFutureHandle handle, + FutureData* future_data, const std::string& result); + +// Mark a Future as complete +void CompleteFuture(int error, const char* error_msg, + SafeFutureHandle handle, FutureData* future_data, + User* user); + +// Mark a Future as complete +void CompleteFuture(int error, const char* error_msg, + SafeFutureHandle handle, + FutureData* future_data, SignInResult result); + +// For calls that aren't asynchronous, create and complete a Future at +// the same time. +Future CreateAndCompleteFuture(int fn_idx, int error, + const char* error_msg, + FutureData* future_data); + +// For calls that aren't asynchronous, create and complete a +// Future at the same time. +Future CreateAndCompleteFuture(int fn_idx, int error, + const char* error_msg, + FutureData* future_data, + const std::string& result); + // Platform-specific method to create the wrapped Auth class. void* CreatePlatformAuth(App* app); @@ -62,7 +122,7 @@ void LogHeartbeat(Auth* auth); // Returns true if `auth_data` has a user that's currently active. inline bool ValidUser(const AuthData* auth_data) { - return auth_data->user_impl != nullptr; + return auth_data->deprecated_fields.user_deprecated->is_valid(); } // Notify all the listeners of the state change. diff --git a/auth/src/data.h b/auth/src/data.h index 3d33719879..54a09264c7 100644 --- a/auth/src/data.h +++ b/auth/src/data.h @@ -27,6 +27,20 @@ namespace firebase { namespace auth { +// @deprecated +// +// Fields that should be removed when the Auth Breaking Changes Deprecation +// window ends. +struct AuthDataDeprecatedFields { + // Used to return User* objects from deprecated methods. + User* user_deprecated; + + // Internal implementation of user_deprecated. This object's contains a + // pointer the platform specific user object, which is updated on User + // operations. + UserInternal* user_internal_deprecated; +}; + // Enumeration for API functions that return a Future. // This allows us to hold a Future for the most recent call to that API. enum AuthApiFunction { @@ -41,7 +55,15 @@ enum AuthApiFunction { kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED, kAuthFn_SendPasswordResetEmail, - // External functions in the User API. + // Internal functions that are still handles, but are only used internally: + kInternalFn_GetTokenForRefresher, + kInternalFn_GetTokenForFunctionRegistry, + + kAuthFnCount +}; + +// Constants representing each User function that returns a Future. +enum UserFn { kUserFn_GetToken, kUserFn_UpdateEmail, kUserFn_UpdatePassword, @@ -51,7 +73,7 @@ enum AuthApiFunction { kUserFn_ConfirmEmailVerification, kUserFn_UpdateUserProfile, kUserFn_LinkWithCredential_DEPRECATED, - kUserFn_LinkAndRetrieveDataWithCredential, + kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED, kUserFn_LinkWithProvider_DEPRECATED, kUserFn_ReauthenticateWithProvider_DEPRECATED, kUserFn_Unlink_DEPRECATED, @@ -59,11 +81,7 @@ enum AuthApiFunction { kUserFn_Reload, kUserFn_Delete, - // Internal functions that are still handles, but are only used internally: - kInternalFn_GetTokenForRefresher, - kInternalFn_GetTokenForFunctionRegistry, - - kNumAuthFunctions + kUserFnCount }; /// Delete all the user_infos in auth_data and reset the length to zero. @@ -76,10 +94,8 @@ struct AuthData { AuthData() : app(nullptr), auth(nullptr), - future_impl(kNumAuthFunctions), - current_user(this), + future_impl(kAuthFnCount), auth_impl(nullptr), - user_impl(nullptr), listener_impl(nullptr), id_token_listener_impl(nullptr), expect_id_token_listener_callback(false), @@ -96,7 +112,6 @@ struct AuthData { app = nullptr; auth = nullptr; auth_impl = nullptr; - user_impl = nullptr; listener_impl = nullptr; id_token_listener_impl = nullptr; } @@ -116,23 +131,24 @@ struct AuthData { /// Backpointer to the external Auth class that holds this internal data. Auth* auth; + /// @deprecated Remove when Auth deprecation APIs are removed. + /// + /// Contains a User object that's updated whenever the current user changes. + /// This is used to return User* values from deprecated Auth and User + /// methods. These methods have been replaced with methods that return + /// Users by value (now that we can copy users.) + AuthDataDeprecatedFields deprecated_fields; + /// Handle calls from Futures that the API returns. ReferenceCountedFutureImpl future_impl; /// Identifier used to track futures associated with future_impl. std::string future_api_id; - /// Unique user for this Auth. Note: we only support one user per Auth. - User current_user; - /// Platform-dependent implementation of Auth (that we're wrapping). /// For example, on Android `jobject`. void* auth_impl; - /// Platform-dependent implementation of User (that we're wrapping). - /// For example, on iOS `FIRUser`. - void* user_impl; - /// Platform-dependent implementation of AuthStateListener (that we're /// wrapping). For example, on Android `jobject`. void* listener_impl; diff --git a/auth/src/desktop/user_desktop.h b/auth/src/desktop/user_desktop.h index f03a6f9f3c..40af4762ad 100644 --- a/auth/src/desktop/user_desktop.h +++ b/auth/src/desktop/user_desktop.h @@ -26,7 +26,51 @@ namespace firebase { namespace auth { -// LINT.IfChange +class UserInternal { + public: + // The user's ID, unique to the Firebase project. + std::string uid; + + // The associated email, if any. + std::string email; + + // The display name, if any. + std::string display_name; + + // Associated photo url, if any. + std::string photo_url; + + // A provider ID for the user e.g. "Facebook". + std::string provider_id; + + // The user's phone number, if any. + std::string phone_number; + + // Whether is anonymous. + bool is_anonymous; + + // Whether email is verified. + bool is_email_verified; + + // Tokens for authentication and authorization. + std::string id_token; // an authorization code or access_token + std::string refresh_token; + std::string access_token; + + // The approximate expiration date of the access token. + std::time_t access_token_expiration_date; + + // Whether or not the user can be authenticated by provider 'password'. + bool has_email_password_credential; + + /// The last sign in UTC timestamp in milliseconds. + /// See https://en.wikipedia.org/wiki/Unix_time for details of UTC. + uint64_t last_sign_in_timestamp; + + /// The Firebase user creation UTC timestamp in milliseconds. + uint64_t creation_timestamp; +}; + // The desktop-specific UserInfo implementation. struct UserInfoImpl { // Note: since Visual Studio 2013 and below don't autogenerate move diff --git a/auth/src/include/firebase/auth.h b/auth/src/include/firebase/auth.h index dd5727d09e..4f6d5e95ba 100644 --- a/auth/src/include/firebase/auth.h +++ b/auth/src/include/firebase/auth.h @@ -48,6 +48,7 @@ struct AuthCompletionHandle; class FederatedAuthProvider; class FederatedOAuthProvider; struct SignInResult; +class UserInternal; /// @brief Firebase authentication object. /// @@ -877,9 +878,13 @@ class FederatedAuthProvider { private: friend class ::firebase::auth::Auth; friend class ::firebase::auth::User; + friend class ::firebase::auth::UserInternal; + virtual Future SignIn(AuthData* auth_data) = 0; - virtual Future Link(AuthData* auth_data) = 0; - virtual Future Reauthenticate(AuthData* auth_data) = 0; + virtual Future Link(AuthData* auth_data, + UserInternal* user_internal) = 0; + virtual Future Reauthenticate(AuthData* auth_data, + UserInternal* user_internal) = 0; }; /// @brief Authenticates with Federated OAuth Providers via the @@ -961,10 +966,13 @@ class FederatedOAuthProvider : public FederatedAuthProvider { private: friend class ::firebase::auth::Auth; + friend class ::firebase::auth::UserInternal; Future SignIn(AuthData* auth_data) override; - Future Link(AuthData* auth_data) override; - Future Reauthenticate(AuthData* auth_data) override; + Future Link(AuthData* auth_data, + UserInternal* user_internal) override; + Future Reauthenticate(AuthData* auth_data, + UserInternal* user_internal) override; FederatedOAuthProviderData provider_data_; #ifdef INTERNAL_EXPERIMENTAL diff --git a/auth/src/include/firebase/auth/credential.h b/auth/src/include/firebase/auth/credential.h index a179d199b6..d87d542e17 100644 --- a/auth/src/include/firebase/auth/credential.h +++ b/auth/src/include/firebase/auth/credential.h @@ -28,6 +28,7 @@ namespace firebase { // Predeclarations. class App; +class UserInternal; /// @cond FIREBASE_APP_INTERNAL template @@ -109,6 +110,7 @@ class Credential { /// @cond FIREBASE_APP_INTERNAL friend class Auth; friend class User; + friend class UserInternal; /// Platform-specific implementation. /// For example, FIRAuthCredential* on iOS. diff --git a/auth/src/include/firebase/auth/types.h b/auth/src/include/firebase/auth/types.h index 3f141ad369..1627e37f8a 100644 --- a/auth/src/include/firebase/auth/types.h +++ b/auth/src/include/firebase/auth/types.h @@ -428,6 +428,9 @@ enum AuthError { kAuthErrorTokenRefreshUnavailable, #endif // INTERNAL_EXEPERIMENTAL + + /// An operation was attempted on an invalid User. + kAuthErrorInvalidUser, }; /// @brief Contains information required to authenticate with a third party diff --git a/auth/src/include/firebase/auth/user.h b/auth/src/include/firebase/auth/user.h index ce3b4b6340..719446266b 100644 --- a/auth/src/include/firebase/auth/user.h +++ b/auth/src/include/firebase/auth/user.h @@ -31,6 +31,7 @@ namespace auth { // Predeclarations. class Auth; +class UserInternal; struct AuthData; class FederatedAuthProvider; @@ -62,7 +63,7 @@ class UserInfoInterface { /// /// @endxmlonly /// - virtual std::string uid() const = 0; + virtual std::string uid() const; /// Gets email associated with the user, if any. /// @@ -72,7 +73,7 @@ class UserInfoInterface { /// /// @endxmlonly /// - virtual std::string email() const = 0; + virtual std::string email() const; /// Gets the display name associated with the user, if any. /// @@ -82,7 +83,7 @@ class UserInfoInterface { /// /// @endxmlonly /// - virtual std::string display_name() const = 0; + virtual std::string display_name() const; /// Gets the photo url associated with the user, if any. /// @@ -92,7 +93,7 @@ class UserInfoInterface { /// /// @endxmlonly /// - virtual std::string photo_url() const = 0; + virtual std::string photo_url() const; /// Gets the provider ID for the user (For example, "Facebook"). /// @@ -102,10 +103,10 @@ class UserInfoInterface { /// /// @endxmlonly /// - virtual std::string provider_id() const = 0; + virtual std::string provider_id() const; /// Gets the phone number for the user, in E.164 format. - virtual std::string phone_number() const = 0; + virtual std::string phone_number() const; }; /// @brief Additional user data returned from an identity provider. @@ -178,8 +179,19 @@ class User : public UserInfoInterface { const char* photo_url; }; + /// Copy Constructor. + User(const User&); + + /// Assignment Operator. + User& operator=(const User& user); + ~User(); + /// Returns whether this User object represents a valid user. Could be false + /// on Users contained with @ref AuthResult structures from failed Auth + /// operations. + bool is_valid() const; + /// The Java Web Token (JWT) that can be used to identify the user to /// the backend. /// @@ -214,7 +226,11 @@ class User : public UserInfoInterface { /// /// @endxmlonly /// - const std::vector& provider_data() const; + std::vector provider_data() const; + + /// @deprecated This is a deprecated method. Please use @ref provider_data + /// instead. + const std::vector& provider_data_DEPRECATED(); /// Sets the email address for the user. /// @@ -332,6 +348,9 @@ class User : public UserInfoInterface { FIREBASE_DEPRECATED Future LinkWithCredentialLastResult_DEPRECATED() const; + /// @deprecated This is a deprecated method. Please use + /// @ref LinkAndRetrieveDataWithCredential(const Credential&) instead. + /// /// Links the user with the given 3rd party credentials. /// /// For example, a Facebook login access token, a Twitter token/token-secret @@ -343,12 +362,15 @@ class User : public UserInfoInterface { /// /// Data from the Identity Provider used to sign-in is returned in the /// @ref AdditionalUserInfo inside @ref SignInResult. - Future LinkAndRetrieveDataWithCredential( - const Credential& credential); + FIREBASE_DEPRECATED Future + LinkAndRetrieveDataWithCredential_DEPRECATED(const Credential& credential); + /// @deprecated + /// /// Get results of the most recent call to - /// @ref LinkAndRetrieveDataWithCredential. - Future LinkAndRetrieveDataWithCredentialLastResult() const; + /// @ref LinkAndRetrieveDataWithCredential_DEPRECATED. + FIREBASE_DEPRECATED Future + LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const; /// @deprecated This is a deprecated method. Please use /// @ref LinkWithProvider(FederatedAuthProvider*) instead. @@ -363,7 +385,7 @@ class User : public UserInfoInterface { /// @note: This operation is supported only on iOS, tvOS and Android /// platforms. On other platforms this method will return a Future with a /// preset error code: kAuthErrorUnimplemented. - Future LinkWithProvider_DEPRECATED( + FIREBASE_DEPRECATED Future LinkWithProvider_DEPRECATED( FederatedAuthProvider* provider) const; /// @deprecated This is a deprecated method. Please use @ref Unlink(const @@ -371,12 +393,12 @@ class User : public UserInfoInterface { /// /// Unlinks the current user from the provider specified. /// Status will be an error if the user is not linked to the given provider. - Future Unlink_DEPRECATED(const char* provider); + FIREBASE_DEPRECATED Future Unlink_DEPRECATED(const char* provider); /// @deprecated /// /// Get results of the most recent call to @ref Unlink. - Future UnlinkLastResult_DEPRECATED() const; + FIREBASE_DEPRECATED Future UnlinkLastResult_DEPRECATED() const; /// @deprecated This is a deprecated method. Please use /// @ref UpdatePhoneNumberCredential(const PhoneAuthCredential&) instead. @@ -386,7 +408,7 @@ class User : public UserInfoInterface { /// shortcut to calling Unlink_DEPRECATED(phone_credential.provider().c_str()) /// and then LinkWithCredential_DEPRECATED(phone_credential). `credential` /// must have been created with @ref PhoneAuthProvider. - Future UpdatePhoneNumberCredential_DEPRECATED( + FIREBASE_DEPRECATED Future UpdatePhoneNumberCredential_DEPRECATED( const Credential& credential); /// @deprecated @@ -501,16 +523,17 @@ class User : public UserInfoInterface { virtual std::string phone_number() const; private: + // @deprecated User references to auth_data should only be needed during + // the Google I/O 23 breaking changes deprecation window. + // + // Internal only. + // + // Constructor of an internal opaque type. Memory ownership of UserInternal + // passes to to this User object. + User(AuthData* auth_data, UserInternal* user_internal); + /// @cond FIREBASE_APP_INTERNAL friend struct AuthData; - // Only exists in AuthData. Access via @ref Auth::CurrentUser(). - explicit User(AuthData* auth_data) : auth_data_(auth_data) {} - - // Disable copy constructor. - User(const User&) = delete; - // Disable copy operator. - User& operator=(const User&) = delete; - /// @endcond #if defined(INTERNAL_EXPERIMENTAL) // Doxygen should not make docs for this function. @@ -525,6 +548,7 @@ class User : public UserInfoInterface { // Use the pimpl mechanism to hide data details in the cpp files. AuthData* auth_data_; + UserInternal* user_internal_; }; } // namespace auth diff --git a/auth/src/ios/auth_ios.mm b/auth/src/ios/auth_ios.mm index c004c595ff..428f3ab80b 100644 --- a/auth/src/ios/auth_ios.mm +++ b/auth/src/ios/auth_ios.mm @@ -156,6 +156,13 @@ void UpdateCurrentUser(AuthData *auth_data) { // Platform-specific method to initialize AuthData. void Auth::InitPlatformAuth(AuthData *auth_data) { + // Create persistent User data to continue to facilitate deprecated aysnc + // methods which return a pointer to a User. Remove this structure when those + // deprecated methods are removed. + auth_data->deprecated_fields.user_internal_deprecated = new UserInternal((FIRUser *)nil); + auth_data->deprecated_fields.user_deprecated = + new User(auth_data, auth_data->deprecated_fields.user_internal_deprecated); + FIRCPPAuthListenerHandle *listener_cpp_handle = [[FIRCPPAuthListenerHandle alloc] init]; listener_cpp_handle.authData = auth_data; reinterpret_cast(auth_data->auth_impl)->listener_handle = listener_cpp_handle; @@ -218,6 +225,13 @@ void UpdateCurrentUser(AuthData *auth_data) { SetUserImpl(auth_data, nullptr); + auth_data->deprecated_fields.user_internal_deprecated = nullptr; + + // This also deletes auth_data->deprecated_fields.user_internal_deprecated + // since User has ownership of the UserInternal allocation. + delete auth_data->deprecated_fields.user_deprecated; + auth_data->deprecated_fields.user_deprecated = nullptr; + // Release the FIRAuth* that we allocated in CreatePlatformAuth(). delete auth_data_ios; auth_data->auth_impl = nullptr; @@ -255,18 +269,19 @@ void LogHeartbeat(Auth *auth) { return MakeFuture(&futures, handle); } -// It's safe to return a direct pointer to `current_user` because that class -// holds nothing but a pointer to AuthData, which never changes. -// All User functions that require synchronization go through AuthData's mutex. +// Support the deprecated current_user method by returning a pointer to the +// User contained within Auth. This maintains the older behavior of +// current_user() via current_user_DEPRECATED throughout the deprecation +// window. User *Auth::current_user_DEPRECATED() { if (!auth_data_) return nullptr; MutexLock lock(auth_data_->future_impl.mutex()); - - // auth_data_->current_user should be available after Auth is created because - // [AuthImpl(auth_data) currentUser] is called during Auth::InitPlatformAuth() - // and it would block until persistence is loaded. - User *user = auth_data_->user_impl == nullptr ? nullptr : &auth_data_->current_user; - return user; + if (auth_data_->deprecated_fields.user_deprecated == nullptr || + !auth_data_->deprecated_fields.user_deprecated->is_valid()) { + return nullptr; + } else { + return auth_data_->deprecated_fields.user_deprecated; + } } static User *AssignUser(FIRUser *_Nullable user, AuthData *auth_data) { @@ -276,8 +291,7 @@ void LogHeartbeat(Auth *auth) { SetUserImpl(auth_data, user); } - // If the returned `user` is non-null then the current user is active. - return auth_data->user_impl == nullptr ? nullptr : &auth_data->current_user; + return auth_data->deprecated_fields.user_deprecated; } std::string Auth::language_code() const { @@ -315,27 +329,31 @@ AuthError AuthErrorFromNSError(NSError *_Nullable error) { } void SignInCallback(FIRUser *_Nullable user, NSError *_Nullable error, - SafeFutureHandle handle, AuthData *auth_data) { + SafeFutureHandle handle, ReferenceCountedFutureImpl &future_impl, + AuthData *auth_data) { User *result = AssignUser(user, auth_data); - // Finish off the asynchronous call so that the caller can read it. - ReferenceCountedFutureImpl &futures = auth_data->future_impl; - futures.CompleteWithResult(handle, AuthErrorFromNSError(error), - util::NSStringToString(error.localizedDescription).c_str(), result); + if (future_impl.ValidFuture(handle)) { + // Finish off the asynchronous call so that the caller can read it. + future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + util::NSStringToString(error.localizedDescription).c_str(), + result); + } } void SignInResultWithProviderCallback( FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error, - SafeFutureHandle handle, AuthData *_Nonnull auth_data, - const FIROAuthProvider *_Nonnull ios_auth_provider /*unused */) { + SafeFutureHandle handle, ReferenceCountedFutureImpl &future_impl, + AuthData *_Nonnull auth_data, const FIROAuthProvider *_Nonnull ios_auth_provider /*unused */) { // ios_auth_provider exists as a parameter to hold a reference to the FIROAuthProvider preventing // its release by the Objective-C runtime during the asynchronous SignIn operation. error = RemapBadProviderIDErrors(error); - SignInResultCallback(auth_result, error, handle, auth_data); + SignInResultCallback(auth_result, error, handle, future_impl, auth_data); } void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error, - SafeFutureHandle handle, AuthData *auth_data) { + SafeFutureHandle handle, + ReferenceCountedFutureImpl &future_impl, AuthData *auth_data) { User *user = AssignUser(auth_result.user, auth_data); SignInResult result; @@ -355,9 +373,11 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu } } - ReferenceCountedFutureImpl &futures = auth_data->future_impl; - futures.CompleteWithResult(handle, AuthErrorFromNSError(error), - util::NSStringToString(error.localizedDescription).c_str(), result); + if (future_impl.ValidFuture(handle)) { + future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + util::NSStringToString(error.localizedDescription).c_str(), + result); + } } Future Auth::SignInWithCustomToken_DEPRECATED(const char *token) { @@ -367,7 +387,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu [AuthImpl(auth_data_) signInWithCustomToken:@(token) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, auth_data_); + SignInCallback(auth_result.user, error, handle, futures, auth_data_); }]; return MakeFuture(&futures, handle); @@ -380,7 +400,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu [AuthImpl(auth_data_) signInWithCredential:CredentialFromImpl(credential.impl_) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, auth_data_); + SignInCallback(auth_result.user, error, handle, futures, auth_data_); }]; return MakeFuture(&futures, handle); @@ -395,7 +415,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu [AuthImpl(auth_data_) signInWithCredential:CredentialFromImpl(credential.impl_) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInResultCallback(auth_result, error, handle, auth_data_); + SignInResultCallback(auth_result, error, handle, futures, auth_data_); }]; return MakeFuture(&futures, handle); @@ -413,7 +433,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu [AuthImpl(auth_data_) signInAnonymouslyWithCompletion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, auth_data_); + SignInCallback(auth_result.user, error, handle, futures, auth_data_); }]; return MakeFuture(&futures, handle); @@ -433,7 +453,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu signInWithEmail:@(email) password:@(password) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, auth_data_); + SignInCallback(auth_result.user, error, handle, futures, auth_data_); }]; } return MakeFuture(&futures, handle); @@ -453,7 +473,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu createUserWithEmail:@(email) password:@(password) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, auth_data_); + SignInCallback(auth_result.user, error, handle, futures, auth_data_); }]; } return MakeFuture(&futures, handle); diff --git a/auth/src/ios/common_ios.h b/auth/src/ios/common_ios.h index d6d471e811..f5d8809752 100644 --- a/auth/src/ios/common_ios.h +++ b/auth/src/ios/common_ios.h @@ -26,9 +26,13 @@ #import "FIRUserInfo.h" #import "FIRUserMetadata.h" +#include +#include + #include "app/src/log.h" #include "app/src/util_ios.h" #include "auth/src/common.h" +#include "auth/src/include/firebase/auth.h" #include "auth/src/include/firebase/auth/user.h" @class FIRCPPAuthListenerHandle; @@ -50,25 +54,118 @@ struct AuthDataIos { FIRCPPAuthListenerHandlePointer listener_handle; }; -/// Convert from the platform-independent void* to the Obj-C FIRUser pointer. -static inline FIRUser *_Nullable UserImpl(AuthData *_Nonnull auth_data) { - return FIRUserPointer::SafeGet(static_cast(auth_data->user_impl)); -} +// Contains the interface between the public API and the underlying +// Obj-C SDK FirebaseUser implemention. +class UserInternal { + public: + // Constructor + explicit UserInternal(FIRUser *user); + + // Copy constructor. + UserInternal(const UserInternal &user_internal); + + ~UserInternal(); + + // @deprecated + // + // Provides a mechanism for the deprecated auth-contained user object to + // update its underlying FIRUser data. + void set_native_user_object_deprecated(FIRUser *user); + + bool is_valid() const; + + Future GetToken(bool force_refresh); + Future GetTokenLastResult() const; + + Future UpdateEmail(const char *email); + Future UpdateEmailLastResult() const; + + std::vector provider_data() const; + const std::vector &provider_data_DEPRECATED(); + + Future UpdatePassword(const char *password); + Future UpdatePasswordLastResult() const; + + Future UpdateUserProfile(const User::UserProfile &profile); + Future UpdateUserProfileLastResult() const; + + Future SendEmailVerification(); + Future SendEmailVerificationLastResult() const; + + Future LinkWithCredential_DEPRECATED(AuthData *auth_data, const Credential &credential); + Future LinkWithCredentialLastResult_DEPRECATED() const; + + Future LinkAndRetrieveDataWithCredential_DEPRECATED(AuthData *auth_data_, + const Credential &credential); + Future LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const; + + Future LinkWithProvider_DEPRECATED(AuthData *auth_data, + FederatedAuthProvider *provider); + Future LinkWithProviderLastResult_DEPRECATED() const; -/// Release the platform-dependent FIRUser object. -static inline void SetUserImpl(AuthData *_Nonnull auth_data, FIRUser *_Nullable user) { - MutexLock lock(auth_data->future_impl.mutex()); + Future Unlink_DEPRECATED(AuthData *auth_data, const char *provider); + Future UnlinkLastResult_DEPRECATED() const; - // Delete existing pointer to FIRUser. - if (auth_data->user_impl != nullptr) { - delete static_cast(auth_data->user_impl); - auth_data->user_impl = nullptr; - } + Future UpdatePhoneNumberCredential_DEPRECATED(AuthData *auth_data, + const Credential &credential); + Future UpdatePhoneNumberCredentialLastResult_DEPRECATED() const; + + Future Reload(); + Future ReloadLastResult() const; + + Future Reauthenticate(const Credential &credential); + Future ReauthenticateLastResult() const; + + Future ReauthenticateAndRetrieveData_DEPRECATED(AuthData *auth_data, + const Credential &credential); + Future ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const; + + Future ReauthenticateWithProvider_DEPRECATED(AuthData *auth_data, + FederatedAuthProvider *provider); + Future ReauthenticateWithProviderLastResult_DEPRECATED() const; + + Future Delete(AuthData *auth_data); + Future DeleteLastResult() const; + + UserMetadata metadata() const; + bool is_email_verified() const; + bool is_anonymous() const; + std::string uid() const; + std::string email() const; + std::string display_name() const; + std::string phone_number() const; + std::string photo_url() const; + std::string provider_id() const; + + private: + friend class firebase::auth::FederatedOAuthProvider; + friend class firebase::auth::User; + + void clear_user_infos(); + + // Obj-c Implementation of a User object. + FIRUser *user_; + + // Future data used to synchronize asynchronous calls. + FutureData future_data_; + + // Used to support older method invocation of provider_data_DEPRECATED(). + std::vector user_infos_; + + // Guard the creation and deletion of the vector of UserInfoInterface* + // allocations in provider_data_DEPRECATED(). + Mutex user_info_mutex_deprecated_; + + // Guard against changes to the user_ object. + Mutex user_mutex_; +}; - // Create new pointer to FIRUser. - if (user != nullptr) { - auth_data->user_impl = new FIRUserPointer(user); - } +/// Replace the platform-dependent FIRUser object. +/// Note: this function is only used to support DEPRECATED methods which return User*. This +/// functionality should be removed when those deprecated methods are removed. +static inline void SetUserImpl(AuthData *_Nonnull auth_data, FIRUser *_Nullable ios_user) { + auth_data->deprecated_fields.user_internal_deprecated->set_native_user_object_deprecated( + ios_user); } /// Convert from the platform-independent void* to the Obj-C FIRAuth pointer. @@ -87,12 +184,14 @@ AuthError AuthErrorFromNSError(NSError *_Nullable error); /// Common code for all API calls that return a User*. /// Initialize `auth_data->current_user` and complete the `future`. void SignInCallback(FIRUser *_Nullable user, NSError *_Nullable error, - SafeFutureHandle handle, AuthData *_Nonnull auth_data); + SafeFutureHandle handle, ReferenceCountedFutureImpl &future_impl, + AuthData *_Nonnull auth_data); /// Common code for all API calls that return a SignInResult. /// Initialize `auth_data->current_user` and complete the `future`. void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error, - SafeFutureHandle handle, AuthData *_Nonnull auth_data); + SafeFutureHandle handle, + ReferenceCountedFutureImpl &future_impl, AuthData *_Nonnull auth_data); /// Common code for all FederatedOAuth API calls which return a SignInResult and /// must hold a reference to a FIROAuthProvider so that the provider is not @@ -101,6 +200,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu void SignInResultWithProviderCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error, SafeFutureHandle handle, + ReferenceCountedFutureImpl &future_impl, AuthData *_Nonnull auth_data, const FIROAuthProvider *_Nonnull ios_auth_provider); diff --git a/auth/src/ios/credential_ios.mm b/auth/src/ios/credential_ios.mm index e256956f34..8a6daaaba7 100644 --- a/auth/src/ios/credential_ios.mm +++ b/auth/src/ios/credential_ios.mm @@ -408,21 +408,20 @@ explicit PhoneAuthProviderData(FIRPhoneAuthProvider* objc_provider) void LinkWithProviderGetCredentialCallback(FIRAuthCredential* _Nullable credential, NSError* _Nullable error, SafeFutureHandle handle, - AuthData* auth_data, + ReferenceCountedFutureImpl& future_impl, + AuthData* auth_data, FIRUser* user, const FIROAuthProvider* ios_auth_provider) { if (error && error.code != 0) { - ReferenceCountedFutureImpl& futures = auth_data->future_impl; error = RemapBadProviderIDErrors(error); - futures.CompleteWithResult(handle, AuthErrorFromNSError(error), - util::NSStringToString(error.localizedDescription).c_str(), - SignInResult()); + future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + util::NSStringToString(error.localizedDescription).c_str(), + SignInResult()); } else { - [UserImpl(auth_data) - linkWithCredential:credential - completion:^(FIRAuthDataResult* _Nullable auth_result, NSError* _Nullable error) { - SignInResultWithProviderCallback(auth_result, error, handle, auth_data, - ios_auth_provider); - }]; + [user linkWithCredential:credential + completion:^(FIRAuthDataResult* _Nullable auth_result, NSError* _Nullable error) { + SignInResultWithProviderCallback(auth_result, error, handle, future_impl, + auth_data, ios_auth_provider); + }]; } } @@ -432,22 +431,22 @@ void LinkWithProviderGetCredentialCallback(FIRAuthCredential* _Nullable credenti void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullable credential, NSError* _Nullable error, SafeFutureHandle handle, - AuthData* auth_data, + ReferenceCountedFutureImpl& future_impl, + AuthData* auth_data, FIRUser* user, const FIROAuthProvider* ios_auth_provider) { if (error && error.code != 0) { - ReferenceCountedFutureImpl& futures = auth_data->future_impl; error = RemapBadProviderIDErrors(error); - futures.CompleteWithResult(handle, AuthErrorFromNSError(error), - util::NSStringToString(error.localizedDescription).c_str(), - SignInResult()); + future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + util::NSStringToString(error.localizedDescription).c_str(), + SignInResult()); } else { - [UserImpl(auth_data) - reauthenticateWithCredential:credential - completion:^(FIRAuthDataResult* _Nullable auth_result, - NSError* _Nullable error) { - SignInResultWithProviderCallback(auth_result, error, handle, auth_data, - ios_auth_provider); - }]; + [user reauthenticateWithCredential:credential + completion:^(FIRAuthDataResult* _Nullable auth_result, + NSError* _Nullable error) { + SignInResultWithProviderCallback(auth_result, error, handle, + future_impl, auth_data, + ios_auth_provider); + }]; } } @@ -466,7 +465,7 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl signInWithProvider:ios_provider UIDelegate:nullptr completion:^(FIRAuthDataResult* _Nullable auth_result, NSError* _Nullable error) { - SignInResultWithProviderCallback(auth_result, error, handle, auth_data, + SignInResultWithProviderCallback(auth_result, error, handle, futures, auth_data, ios_provider); }]; return MakeFuture(&futures, handle); @@ -478,11 +477,12 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl } } -Future FederatedOAuthProvider::Link(AuthData* auth_data) { +Future FederatedOAuthProvider::Link(AuthData* auth_data, + UserInternal* user_internal) { assert(auth_data); - ReferenceCountedFutureImpl& futures = auth_data->future_impl; - auto handle = - futures.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + assert(user_internal); + auto handle = user_internal->future_data_.future_impl.SafeAlloc( + kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) @@ -490,34 +490,39 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl if (ios_provider != nullptr) { ios_provider.customParameters = util::StringMapToNSDictionary(provider_data_.custom_parameters); ios_provider.scopes = util::StringVectorToNSMutableArray(provider_data_.scopes); + FIRUser* user = user_internal->user_; // TODO(b/138788092) invoke FIRUser linkWithProvider instead, once that method is added to the // iOS SDK. - [ios_provider getCredentialWithUIDelegate:nullptr - completion:^(FIRAuthCredential* _Nullable credential, - NSError* _Nullable error) { - LinkWithProviderGetCredentialCallback( - credential, error, handle, auth_data, ios_provider); - }]; - return MakeFuture(&futures, handle); + [ios_provider + getCredentialWithUIDelegate:nullptr + completion:^(FIRAuthCredential* _Nullable credential, + NSError* _Nullable error) { + LinkWithProviderGetCredentialCallback( + credential, error, handle, user_internal->future_data_.future_impl, + auth_data, user, ios_provider); + }]; + return MakeFuture(&user_internal->future_data_.future_impl, handle); } else { - Future future = MakeFuture(&futures, handle); - futures.CompleteWithResult(handle, kAuthErrorFailure, "Internal error constructing provider.", - SignInResult()); + Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); + user_internal->future_data_.future_impl.CompleteWithResult( + handle, kAuthErrorFailure, "Internal error constructing provider.", SignInResult()); return future; } #else // non-iOS Apple platforms (eg: tvOS) - Future future = MakeFuture(&futures, handle); - futures.Complete(handle, kAuthErrorApiNotAvailable, - "OAuth provider linking is not supported on non-iOS Apple platforms."); + Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); + user_internal->future_data_.future_impl.Complete( + handle, kAuthErrorApiNotAvailable, + "OAuth provider linking is not supported on non-iOS Apple platforms."); #endif // FIREBASE_PLATFORM_IOS } -Future FederatedOAuthProvider::Reauthenticate(AuthData* auth_data) { +Future FederatedOAuthProvider::Reauthenticate(AuthData* auth_data, + UserInternal* user_internal) { assert(auth_data); - ReferenceCountedFutureImpl& futures = auth_data->future_impl; - auto handle = - futures.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + assert(user_internal); + auto handle = user_internal->future_data_.future_impl.SafeAlloc( + kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) @@ -525,26 +530,30 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl if (ios_provider != nullptr) { ios_provider.customParameters = util::StringMapToNSDictionary(provider_data_.custom_parameters); ios_provider.scopes = util::StringVectorToNSMutableArray(provider_data_.scopes); + FIRUser* user = user_internal->user_; // TODO(b/138788092) invoke FIRUser:reuthenticateWithProvider instead, once that method is added // to the iOS SDK. - [ios_provider getCredentialWithUIDelegate:nullptr - completion:^(FIRAuthCredential* _Nullable credential, - NSError* _Nullable error) { - ReauthenticateWithProviderGetCredentialCallback( - credential, error, handle, auth_data, ios_provider); - }]; - return MakeFuture(&futures, handle); + [ios_provider + getCredentialWithUIDelegate:nullptr + completion:^(FIRAuthCredential* _Nullable credential, + NSError* _Nullable error) { + ReauthenticateWithProviderGetCredentialCallback( + credential, error, handle, user_internal->future_data_.future_impl, + auth_data, user, ios_provider); + }]; + return MakeFuture(&user_internal->future_data_.future_impl, handle); } else { - Future future = MakeFuture(&futures, handle); - futures.CompleteWithResult(handle, kAuthErrorFailure, "Internal error constructing provider.", - SignInResult()); + Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); + user_internal->future_data_.future_impl.CompleteWithResult( + handle, kAuthErrorFailure, "Internal error constructing provider.", SignInResult()); return future; } #else // non-iOS Apple platforms (eg: tvOS) - Future future = MakeFuture(&futures, handle); - futures.Complete(handle, kAuthErrorApiNotAvailable, - "OAuth reauthentication is not supported on non-iOS Apple platforms."); + Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); + user_internal->future_data_.future_impl.Complete( + handle, kAuthErrorApiNotAvailable, + "OAuth reauthentication is not supported on non-iOS Apple platforms."); #endif // FIREBASE_PLATFORM_IOS } diff --git a/auth/src/ios/user_ios.mm b/auth/src/ios/user_ios.mm index 56d507ab29..80d48c20c4 100644 --- a/auth/src/ios/user_ios.mm +++ b/auth/src/ios/user_ios.mm @@ -19,6 +19,7 @@ #if FIREBASE_PLATFORM_IOS #import "FIRPhoneAuthCredential.h" +#import "FIRUser.h" #endif namespace firebase { @@ -29,108 +30,407 @@ const char kInvalidCredentialMessage[] = "Credential is not a phone credential."; +/// +/// User Class +/// Platform specific implementation +/// +User::User(AuthData *auth_data, UserInternal *user_internal) { + assert(auth_data); + if (user_internal == nullptr) { + // Create an invalid user internal. + // This will return is_valid() false, and operations will fail. + user_internal_ = new UserInternal(nullptr); + } else { + user_internal_ = user_internal; + } + auth_data_ = auth_data; +} + +User::~User() { + delete user_internal_; + user_internal_ = nullptr; + auth_data_ = nullptr; +} + +User &User::operator=(const User &user) { + assert(user_internal_); + delete user_internal_; + if (user.user_internal_ != nullptr) { + user_internal_ = new UserInternal(user.user_internal_->user_); + } else { + user_internal_ = new UserInternal(nullptr); + } + auth_data_ = user.auth_data_; + return *this; +} + +bool User::is_valid() const { + assert(user_internal_); + return user_internal_->is_valid(); +} + +Future User::GetToken(bool force_refresh) { + assert(user_internal_); + return user_internal_->GetToken(force_refresh); +} + +std::vector User::provider_data() const { + assert(user_internal_); + return user_internal_->provider_data(); +} + +const std::vector &User::provider_data_DEPRECATED() { + assert(user_internal_); + return user_internal_->provider_data_DEPRECATED(); +} + +Future User::UpdateEmail(const char *email) { + assert(user_internal_); + return user_internal_->UpdateEmail(email); +} + +Future User::UpdateEmailLastResult() const { + assert(user_internal_); + return user_internal_->UpdateEmailLastResult(); +} + +Future User::UpdatePassword(const char *password) { + assert(user_internal_); + return user_internal_->UpdatePassword(password); +} + +Future User::UpdatePasswordLastResult() const { + assert(user_internal_); + return user_internal_->UpdatePasswordLastResult(); +} + +Future User::Reauthenticate(const Credential &credential) { + assert(user_internal_); + return user_internal_->Reauthenticate(credential); +} + +Future User::ReauthenticateLastResult() const { + assert(user_internal_); + return user_internal_->ReauthenticateLastResult(); +} + +Future User::ReauthenticateAndRetrieveData_DEPRECATED(const Credential &credential) { + assert(user_internal_); + return user_internal_->ReauthenticateAndRetrieveData_DEPRECATED(auth_data_, credential); +} + +Future User::ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_->ReauthenticateAndRetrieveDataLastResult_DEPRECATED(); +} + +Future User::ReauthenticateWithProvider_DEPRECATED( + FederatedAuthProvider *provider) const { + assert(user_internal_); + return user_internal_->ReauthenticateWithProvider_DEPRECATED(auth_data_, provider); +} + +Future User::SendEmailVerification() { + assert(user_internal_); + return user_internal_->SendEmailVerification(); +} + +Future User::SendEmailVerificationLastResult() const { + assert(user_internal_); + return user_internal_->SendEmailVerificationLastResult(); +} + +Future User::UpdateUserProfile(const UserProfile &profile) { + assert(user_internal_); + return user_internal_->UpdateUserProfile(profile); +} + +Future User::UpdateUserProfileLastResult() const { + assert(user_internal_); + return user_internal_->UpdateUserProfileLastResult(); +} + +Future User::LinkWithCredential_DEPRECATED(const Credential &credential) { + assert(user_internal_); + return user_internal_->LinkWithCredential_DEPRECATED(auth_data_, credential); +} + +Future User::LinkWithCredentialLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_->LinkWithCredentialLastResult_DEPRECATED(); +} + +Future User::LinkAndRetrieveDataWithCredential_DEPRECATED( + const Credential &credential) { + assert(user_internal_); + return user_internal_->LinkAndRetrieveDataWithCredential_DEPRECATED(auth_data_, credential); +} + +Future User::LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_->LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED(); +} + +Future User::LinkWithProvider_DEPRECATED(FederatedAuthProvider *provider) const { + assert(user_internal_); + return user_internal_->LinkWithProvider_DEPRECATED(auth_data_, provider); +} + +Future User::Unlink_DEPRECATED(const char *provider) { + assert(user_internal_); + return user_internal_->Unlink_DEPRECATED(auth_data_, provider); +} + +Future User::UnlinkLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_->UnlinkLastResult_DEPRECATED(); +} + +Future User::UpdatePhoneNumberCredential_DEPRECATED(const Credential &credential) { + assert(user_internal_); + return user_internal_->UpdatePhoneNumberCredential_DEPRECATED(auth_data_, credential); +} + +Future User::Reload() { + assert(user_internal_); + return user_internal_->Reload(); +} + +Future User::ReloadLastResult() const { + assert(user_internal_); + return user_internal_->ReloadLastResult(); +} + +Future User::Delete() { + assert(user_internal_); + return user_internal_->Delete(auth_data_); +} + +Future User::DeleteLastResult() const { + assert(user_internal_); + return user_internal_->DeleteLastResult(); +} + +UserMetadata User::metadata() const { + assert(user_internal_); + return user_internal_->metadata(); +} + +bool User::is_email_verified() const { + assert(user_internal_); + return user_internal_->is_email_verified(); +} + +bool User::is_anonymous() const { + assert(user_internal_); + return user_internal_->is_anonymous(); +} + +std::string User::uid() const { + assert(user_internal_); + return user_internal_->uid(); +} + +std::string User::email() const { + assert(user_internal_); + return user_internal_->email(); +} + +std::string User::display_name() const { + assert(user_internal_); + return user_internal_->display_name(); +} + +std::string User::photo_url() const { + assert(user_internal_); + return user_internal_->photo_url(); +} + +std::string User::provider_id() const { + assert(user_internal_); + return user_internal_->provider_id(); +} + +std::string User::phone_number() const { + assert(user_internal_); + return user_internal_->phone_number(); +} + +/// +/// IOSWrapperUserInfo Class +/// class IOSWrappedUserInfo : public UserInfoInterface { public: explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) {} virtual ~IOSWrappedUserInfo() { user_info_ = nil; } - virtual std::string uid() const { return StringFromNSString(user_info_.uid); } + std::string uid() const override { return StringFromNSString(user_info_.uid); } - virtual std::string email() const { return StringFromNSString(user_info_.email); } + std::string email() const override { return StringFromNSString(user_info_.email); } - virtual std::string display_name() const { return StringFromNSString(user_info_.displayName); } + std::string display_name() const override { return StringFromNSString(user_info_.displayName); } - virtual std::string phone_number() const { return StringFromNSString(user_info_.phoneNumber); } + std::string phone_number() const override { return StringFromNSString(user_info_.phoneNumber); } - virtual std::string photo_url() const { return StringFromNSUrl(user_info_.photoURL); } + std::string photo_url() const override { return StringFromNSUrl(user_info_.photoURL); } - virtual std::string provider_id() const { return StringFromNSString(user_info_.providerID); } + std::string provider_id() const override { return StringFromNSString(user_info_.providerID); } private: - /// Pointer to the main class. - /// Needed for context in implementation of virtuals. id user_info_; }; -User::~User() { +/// +/// UserInternal Class +/// +UserInternal::UserInternal(FIRUser *user) : user_(user), future_data_(kUserFnCount) {} + +UserInternal::UserInternal(const UserInternal &user_internal) + : user_(user_internal.user_), future_data_(kUserFnCount) {} + +UserInternal::~UserInternal() { + user_ = nil; + { + MutexLock user_info_lock(user_info_mutex_deprecated_); + clear_user_infos(); + } // Make sure we don't have any pending futures in flight before we disappear. - while (!auth_data_->future_impl.IsSafeToDelete()) { + while (!future_data_.future_impl.IsSafeToDelete()) { internal::Sleep(100); } } -Future User::GetToken(bool force_refresh) { - if (!ValidUser(auth_data_)) { - return Future(); +void UserInternal::set_native_user_object_deprecated(FIRUser *user) { + MutexLock user_info_lock(user_mutex_); + user_ = user; +} + +bool UserInternal::is_valid() const { return user_ != nil; } + +void UserInternal::clear_user_infos() { + for (size_t i = 0; i < user_infos_.size(); ++i) { + delete user_infos_[i]; + user_infos_[i] = nullptr; } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_GetToken); - [UserImpl(auth_data_) - getIDTokenForcingRefresh:force_refresh - completion:^(NSString *_Nullable token, NSError *_Nullable error) { - futures.Complete(handle, AuthErrorFromNSError(error), - [error.localizedDescription UTF8String], - [token](std::string *data) { - data->assign(token == nullptr ? "" : [token UTF8String]); - }); - }]; - return MakeFuture(&futures, handle); -} - -const std::vector &User::provider_data() const { - ClearUserInfos(auth_data_); - - if (ValidUser(auth_data_)) { - NSArray> *provider_data = UserImpl(auth_data_).providerData; - - // Wrap the FIRUserInfos in our IOSWrappedUserInfo class. - auth_data_->user_infos.resize(provider_data.count); + user_infos_.clear(); +} + +Future UserInternal::GetToken(bool force_refresh) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_GetToken, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_, ""); + } + + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc(kUserFn_GetToken)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ getIDTokenForcingRefresh:force_refresh + completion:^(NSString *_Nullable token, NSError *_Nullable error) { + callback_data->future_data->future_impl.Complete( + callback_data->future_handle, AuthErrorFromNSError(error), + [error.localizedDescription UTF8String], [token](std::string *data) { + data->assign(token == nullptr ? "" : [token UTF8String]); + }); + delete callback_data; + }]; + return future; +} + +std::vector UserInternal::provider_data() const { + std::vector local_user_infos; + if (is_valid()) { + NSArray> *provider_data = user_.providerData; + local_user_infos.resize(provider_data.count); + for (size_t i = 0; i < provider_data.count; ++i) { + local_user_infos[i] = IOSWrappedUserInfo(provider_data[i]); + } + } + return local_user_infos; +} + +const std::vector &UserInternal::provider_data_DEPRECATED() { + MutexLock user_info_lock(user_info_mutex_deprecated_); + clear_user_infos(); + if (is_valid()) { + NSArray> *provider_data = user_.providerData; + user_infos_.resize(provider_data.count); for (size_t i = 0; i < provider_data.count; ++i) { - auth_data_->user_infos[i] = new IOSWrappedUserInfo(provider_data[i]); + user_infos_[i] = new IOSWrappedUserInfo(provider_data[i]); } } // Return a reference to our internally-backed values. - return auth_data_->user_infos; + return user_infos_; } -Future User::UpdateEmail(const char *email) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdateEmail(const char *email) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_UpdateEmail, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdateEmail); - [UserImpl(auth_data_) updateEmail:@(email) - completion:^(NSError *_Nullable error) { - futures.Complete(handle, AuthErrorFromNSError(error), - [error.localizedDescription UTF8String]); - }]; - return MakeFuture(&futures, handle); + + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc(kUserFn_UpdateEmail)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ updateEmail:@(email) + completion:^(NSError *_Nullable error) { + callback_data->future_data->future_impl.Complete( + callback_data->future_handle, AuthErrorFromNSError(error), + [error.localizedDescription UTF8String]); + delete callback_data; + }]; + return future; } -Future User::UpdatePassword(const char *password) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdateEmailLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_UpdateEmail)); +} + +Future UserInternal::UpdatePassword(const char *password) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_UpdatePassword, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdatePassword); - [UserImpl(auth_data_) updatePassword:@(password) - completion:^(NSError *_Nullable error) { - futures.Complete(handle, AuthErrorFromNSError(error), - [error.localizedDescription UTF8String]); - }]; - return MakeFuture(&futures, handle); + + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc(kUserFn_UpdatePassword)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ updatePassword:@(password) + completion:^(NSError *_Nullable error) { + callback_data->future_data->future_impl.Complete( + callback_data->future_handle, AuthErrorFromNSError(error), + [error.localizedDescription UTF8String]); + delete callback_data; + }]; + return future; } -Future User::UpdateUserProfile(const UserProfile &profile) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdatePasswordLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_UpdatePassword)); +} + +Future UserInternal::UpdateUserProfile(const User::UserProfile &profile) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_UpdateUserProfile, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdateUserProfile); + + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc(kUserFn_UpdateUserProfile)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + // Create and populate the change request. - FIRUserProfileChangeRequest *request = [UserImpl(auth_data_) profileChangeRequest]; + FIRUserProfileChangeRequest *request = [user_ profileChangeRequest]; if (profile.display_name != nullptr) { request.displayName = @(profile.display_name); } @@ -143,174 +443,311 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { // Execute the change request. [request commitChangesWithCompletion:^(NSError *_Nullable error) { - futures.Complete(handle, AuthErrorFromNSError(error), [error.localizedDescription UTF8String]); + callback_data->future_data->future_impl.Complete(callback_data->future_handle, + AuthErrorFromNSError(error), + [error.localizedDescription UTF8String]); + delete callback_data; }]; - return MakeFuture(&futures, handle); + + return future; } -Future User::SendEmailVerification() { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdateUserProfileLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_UpdateUserProfile)); +} + +Future UserInternal::SendEmailVerification() { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_SendEmailVerification, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_SendEmailVerification); - [UserImpl(auth_data_) sendEmailVerificationWithCompletion:^(NSError *_Nullable error) { - futures.Complete(handle, AuthErrorFromNSError(error), [error.localizedDescription UTF8String]); + + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc(kUserFn_SendEmailVerification)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ sendEmailVerificationWithCompletion:^(NSError *_Nullable error) { + callback_data->future_data->future_impl.Complete(callback_data->future_handle, + AuthErrorFromNSError(error), + [error.localizedDescription UTF8String]); + delete callback_data; }]; - return MakeFuture(&futures, handle); + + return future; } -Future User::LinkWithCredential_DEPRECATED(const Credential &credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::SendEmailVerificationLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_SendEmailVerification)); +} + +Future UserInternal::LinkWithCredential_DEPRECATED(AuthData *auth_data, + const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_LinkWithCredential_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, future_handle, + &future_data_, (User *)nullptr); + return future; } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_LinkWithCredential_DEPRECATED); - [UserImpl(auth_data_) - linkWithCredential:CredentialFromImpl(credential.impl_) - completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, auth_data_); - }]; - return MakeFuture(&futures, handle); -} - -Future User::LinkAndRetrieveDataWithCredential(const Credential &credential) { - if (!ValidUser(auth_data_)) { - return Future(); + + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, + future_data_.future_impl.SafeAlloc(kUserFn_LinkWithCredential_DEPRECATED)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ linkWithCredential:CredentialFromImpl(credential.impl_) + completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { + SignInCallback(auth_result.user, error, callback_data->future_handle, + callback_data->future_data->future_impl, auth_data); + delete callback_data; + }]; + return future; +} + +Future UserInternal::LinkWithCredentialLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_LinkWithCredential_DEPRECATED)); +} + +Future UserInternal::LinkAndRetrieveDataWithCredential_DEPRECATED( + AuthData *auth_data, const Credential &credential) { + // MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + printf("DEDB LinkAndRetrieveDataWithCredential_DEPRECATED user is not valid\n"); + SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( + kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + return future; } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = auth_data_->future_impl.SafeAlloc( - kUserFn_LinkAndRetrieveDataWithCredential, SignInResult()); - [UserImpl(auth_data_) - linkWithCredential:CredentialFromImpl(credential.impl_) - completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInResultCallback(auth_result, error, handle, auth_data_); - }]; - return MakeFuture(&futures, handle); + + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc( + kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ linkWithCredential:CredentialFromImpl(credential.impl_) + completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { + NSLog(@"DEDB Completion auth_result: %p error: %p\n", auth_result, error); + SignInResultCallback(auth_result, error, callback_data->future_handle, + callback_data->future_data->future_impl, auth_data); + NSLog(@"DEDB Completion SignInResultCallback returned\n"); + // delete callback_data; + }]; + return future; } -Future User::LinkWithProvider_DEPRECATED(FederatedAuthProvider *provider) const { +Future UserInternal::LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED)); +} + +Future UserInternal::LinkWithProvider_DEPRECATED(AuthData *auth_data, + FederatedAuthProvider *provider) { FIREBASE_ASSERT_RETURN(Future(), provider); - return provider->Link(auth_data_); + return provider->Link(auth_data, this); } -Future User::Unlink_DEPRECATED(const char *provider) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::Unlink_DEPRECATED(AuthData *auth_data, const char *provider) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_Unlink_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, future_handle, + &future_data_, (User *)nullptr); + return future; } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Unlink_DEPRECATED); - [UserImpl(auth_data_) unlinkFromProvider:@(provider) - completion:^(FIRUser *_Nullable user, NSError *_Nullable error) { - SignInCallback(user, error, handle, auth_data_); - }]; - return MakeFuture(&futures, handle); + + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc(kUserFn_Unlink_DEPRECATED)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ unlinkFromProvider:@(provider) + completion:^(FIRUser *_Nullable user, NSError *_Nullable error) { + SignInCallback(user, error, callback_data->future_handle, + callback_data->future_data->future_impl, auth_data); + delete callback_data; + }]; + return future; } -Future User::UpdatePhoneNumberCredential_DEPRECATED(const Credential &credential) { - if (!ValidUser(auth_data_)) { - return Future(); - } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdatePhoneNumberCredential_DEPRECATED); +Future UserInternal::UnlinkLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_Unlink_DEPRECATED)); +} +Future UserInternal::UpdatePhoneNumberCredential_DEPRECATED(AuthData *auth_data, + const Credential &credential) { + MutexLock user_info_lock(user_mutex_); #if FIREBASE_PLATFORM_IOS + if (!is_valid()) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_UpdatePhoneNumberCredential_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, future_handle, + &future_data_, (User *)nullptr); + return future; + } + + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, + future_data_.future_impl.SafeAlloc(kUserFn_UpdatePhoneNumberCredential_DEPRECATED)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + FIRAuthCredential *objc_credential = CredentialFromImpl(credential.impl_); if ([objc_credential isKindOfClass:[FIRPhoneAuthCredential class]]) { - [UserImpl(auth_data_) - updatePhoneNumberCredential:(FIRPhoneAuthCredential *)objc_credential - completion:^(NSError *_Nullable error) { - futures.Complete(handle, AuthErrorFromNSError(error), - [error.localizedDescription UTF8String]); - }]; + [user_ updatePhoneNumberCredential:(FIRPhoneAuthCredential *)objc_credential + completion:^(NSError *_Nullable error) { + SignInCallback(user_, error, callback_data->future_handle, + callback_data->future_data->future_impl, auth_data); + delete callback_data; + }]; } else { - futures.Complete(handle, kAuthErrorInvalidCredential, kInvalidCredentialMessage); + CompleteFuture(kAuthErrorInvalidCredential, kInvalidCredentialMessage, + callback_data->future_handle, &future_data_, (User *)nullptr); } + return future; #else // non iOS Apple platforms (eg: tvOS). - futures.Complete(handle, kAuthErrorApiNotAvailable, - "Phone Auth is not supported on non-iOS apple platforms."); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_UpdatePhoneNumberCredential_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + CompleteFuture(kAuthErrorApiNotAvailable, kPhoneAuthNotSupportedErrorMessage, future_handle, + &future_data_, (User *)nullptr); + return future; #endif // FIREBASE_PLATFORM_IOS - - return MakeFuture(&futures, handle); } -Future User::Reload() { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::Reload() { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_Reload, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Reload); - [UserImpl(auth_data_) reloadWithCompletion:^(NSError *_Nullable error) { - futures.Complete(handle, AuthErrorFromNSError(error), [error.localizedDescription UTF8String]); + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc(kUserFn_Reload)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ reloadWithCompletion:^(NSError *_Nullable error) { + callback_data->future_data->future_impl.Complete(callback_data->future_handle, + AuthErrorFromNSError(error), + [error.localizedDescription UTF8String]); + delete callback_data; }]; - return MakeFuture(&futures, handle); + return future; } -Future User::Reauthenticate(const Credential &credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::ReloadLastResult() const { + return static_cast &>(future_data_.future_impl.LastResult(kUserFn_Reload)); +} + +Future UserInternal::Reauthenticate(const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_Reauthenticate, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Reauthenticate); - [UserImpl(auth_data_) - reauthenticateWithCredential:CredentialFromImpl(credential.impl_) - completion:^(FIRAuthDataResult *_Nullable auth_result, - NSError *_Nullable error) { - futures.Complete(handle, AuthErrorFromNSError(error), - [error.localizedDescription UTF8String]); - }]; - return MakeFuture(&futures, handle); + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc(kUserFn_Reauthenticate)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ reauthenticateWithCredential:CredentialFromImpl(credential.impl_) + completion:^(FIRAuthDataResult *_Nullable auth_result, + NSError *_Nullable error) { + callback_data->future_data->future_impl.Complete( + callback_data->future_handle, AuthErrorFromNSError(error), + [error.localizedDescription UTF8String]); + delete callback_data; + }]; + return future; } -Future User::ReauthenticateAndRetrieveData_DEPRECATED(const Credential &credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::ReauthenticateLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_Reauthenticate)); +} + +Future UserInternal::ReauthenticateAndRetrieveData_DEPRECATED( + AuthData *auth_data, const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + return future; } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = auth_data_->future_impl.SafeAlloc( - kUserFn_ReauthenticateAndRetrieveData_DEPRECATED, SignInResult()); - [UserImpl(auth_data_) + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc( + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ reauthenticateWithCredential:CredentialFromImpl(credential.impl_) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInResultCallback(auth_result, error, handle, auth_data_); + SignInResultCallback(auth_result, error, callback_data->future_handle, + callback_data->future_data->future_impl, auth_data); + delete callback_data; }]; - return MakeFuture(&futures, handle); + return future; } -Future User::ReauthenticateWithProvider_DEPRECATED( - FederatedAuthProvider *provider) const { +Future UserInternal::ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_ReauthenticateAndRetrieveData_DEPRECATED)); +} + +Future UserInternal::ReauthenticateWithProvider_DEPRECATED( + AuthData *auth_data, FederatedAuthProvider *provider) { FIREBASE_ASSERT_RETURN(Future(), provider); - return provider->Reauthenticate(auth_data_); + return provider->Reauthenticate(auth_data, this); } -Future User::Delete() { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::Delete(AuthData *auth_data) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_Delete, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Delete); - [UserImpl(auth_data_) deleteWithCompletion:^(NSError *_Nullable error) { + FutureCallbackData *callback_data = new FutureCallbackData{ + &future_data_, future_data_.future_impl.SafeAlloc(kUserFn_Delete)}; + Future future = MakeFuture(&future_data_.future_impl, callback_data->future_handle); + + [user_ deleteWithCompletion:^(NSError *_Nullable error) { if (!error) { - UpdateCurrentUser(auth_data_); - futures.Complete(handle, kAuthErrorNone, ""); + callback_data->future_data->future_impl.Complete(callback_data->future_handle, kAuthErrorNone, + ""); } else { - futures.Complete(handle, AuthErrorFromNSError(error), - [error.localizedDescription UTF8String]); + callback_data->future_data->future_impl.Complete(callback_data->future_handle, + AuthErrorFromNSError(error), + [error.localizedDescription UTF8String]); } + delete callback_data; }]; - return MakeFuture(&futures, handle); + return future; } -UserMetadata User::metadata() const { - if (!ValidUser(auth_data_)) return UserMetadata(); +Future UserInternal::DeleteLastResult() const { + return static_cast &>(future_data_.future_impl.LastResult(kUserFn_Delete)); +} - FIRUserMetadata *meta = UserImpl(auth_data_).metadata; +UserMetadata UserInternal::metadata() const { + if (!is_valid()) return UserMetadata(); + + FIRUserMetadata *meta = user_.metadata; if (!meta) return UserMetadata(); UserMetadata data; @@ -323,36 +760,30 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { return data; } -bool User::is_email_verified() const { - return ValidUser(auth_data_) ? UserImpl(auth_data_).emailVerified : false; -} +bool UserInternal::is_email_verified() const { return is_valid() ? user_.emailVerified : false; } -bool User::is_anonymous() const { - return ValidUser(auth_data_) ? UserImpl(auth_data_).anonymous : false; -} +bool UserInternal::is_anonymous() const { return is_valid() ? user_.anonymous : false; } -std::string User::uid() const { - return ValidUser(auth_data_) ? StringFromNSString(UserImpl(auth_data_).uid) : ""; -} +std::string UserInternal::uid() const { return is_valid() ? StringFromNSString(user_.uid) : ""; } -std::string User::email() const { - return ValidUser(auth_data_) ? StringFromNSString(UserImpl(auth_data_).email) : ""; +std::string UserInternal::email() const { + return is_valid() ? StringFromNSString(user_.email) : ""; } -std::string User::display_name() const { - return ValidUser(auth_data_) ? StringFromNSString(UserImpl(auth_data_).displayName) : ""; +std::string UserInternal::display_name() const { + return is_valid() ? StringFromNSString(user_.displayName) : ""; } -std::string User::phone_number() const { - return ValidUser(auth_data_) ? StringFromNSString(UserImpl(auth_data_).phoneNumber) : ""; +std::string UserInternal::phone_number() const { + return is_valid() ? StringFromNSString(user_.phoneNumber) : ""; } -std::string User::photo_url() const { - return ValidUser(auth_data_) ? StringFromNSUrl(UserImpl(auth_data_).photoURL) : ""; +std::string UserInternal::photo_url() const { + return is_valid() ? StringFromNSUrl(user_.photoURL) : ""; } -std::string User::provider_id() const { - return ValidUser(auth_data_) ? StringFromNSString(UserImpl(auth_data_).providerID) : ""; +std::string UserInternal::provider_id() const { + return is_valid() ? StringFromNSString(user_.providerID) : ""; } } // namespace auth diff --git a/auth/src/user.cc b/auth/src/user.cc index 52693c0b6a..946a565c3e 100644 --- a/auth/src/user.cc +++ b/auth/src/user.cc @@ -19,20 +19,12 @@ namespace firebase { namespace auth { -AUTH_RESULT_FN(User, GetToken, std::string) -AUTH_RESULT_FN(User, UpdateEmail, void) -AUTH_RESULT_FN(User, UpdatePassword, void) -AUTH_RESULT_FN(User, Reauthenticate, void) -AUTH_RESULT_FN(User, SendEmailVerification, void) -AUTH_RESULT_FN(User, UpdateUserProfile, void) -AUTH_RESULT_FN(User, LinkAndRetrieveDataWithCredential, SignInResult) -AUTH_RESULT_FN(User, Reload, void) -AUTH_RESULT_FN(User, Delete, void) - -AUTH_RESULT_DEPRECATED_FN(User, ReauthenticateAndRetrieveData, SignInResult) -AUTH_RESULT_DEPRECATED_FN(User, LinkWithCredential, User*) -AUTH_RESULT_DEPRECATED_FN(User, Unlink, User*) -AUTH_RESULT_DEPRECATED_FN(User, UpdatePhoneNumberCredential, User*) +std::string UserInfoInterface::uid() const { return ""; } +std::string UserInfoInterface::email() const { return ""; } +std::string UserInfoInterface::display_name() const { return ""; } +std::string UserInfoInterface::photo_url() const { return ""; } +std::string UserInfoInterface::provider_id() const { return ""; } +std::string UserInfoInterface::phone_number() const { return ""; } #if defined(INTERNAL_EXPERIMENTAL) // I'd like to change all the above functions to use LastResultProxy, as it From 3116021cd86b361fca19a39fc86840168bbd2f39 Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Thu, 23 Mar 2023 08:02:38 -0400 Subject: [PATCH 08/14] Android compiles --- auth/src/android/auth_android.cc | 129 +-- auth/src/android/common_android.cc | 6 +- auth/src/android/common_android.h | 217 ++++- auth/src/android/credential_android.cc | 95 +- auth/src/android/user_android.cc | 1237 +++++++++++++++++------- auth/src/common.cc | 4 + auth/src/common.h | 8 +- auth/src/include/firebase/auth/types.h | 5 +- auth/src/include/firebase/auth/user.h | 7 +- auth/src/ios/common_ios.h | 10 + auth/src/ios/credential_ios.mm | 2 +- auth/src/ios/user_ios.mm | 34 +- 12 files changed, 1244 insertions(+), 510 deletions(-) diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index 4691b3ada6..21506fe294 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -162,12 +162,10 @@ void ReleaseAuthClasses(JNIEnv* env) { jni_id_token_listener::ReleaseClass(env); } +// Grab the user value from the Android SDK and remember it locally. void UpdateCurrentUser(AuthData* auth_data) { - JNIEnv* env = Env(auth_data); - MutexLock lock(auth_data->future_impl.mutex()); - - const void* original_user_impl = auth_data->user_impl; + JNIEnv* env = Env(auth_data); // Update our pointer to the Android FirebaseUser that we're wrapping. jobject j_user = env->CallObjectMethod( @@ -175,14 +173,8 @@ void UpdateCurrentUser(AuthData* auth_data) { if (firebase::util::CheckAndClearJniExceptions(env)) { j_user = nullptr; } - SetImplFromLocalRef(env, j_user, &auth_data->user_impl); - // Log debug message when user sign-in status has changed. - if (original_user_impl != auth_data->user_impl) { - LogDebug("CurrentUser changed from %X to %X", - reinterpret_cast(original_user_impl), - reinterpret_cast(auth_data->user_impl)); - } + SetUserImpl(auth_data, j_user); } // Release cached Java classes. @@ -294,11 +286,21 @@ void Auth::DestroyPlatformAuth(AuthData* auth_data) { static_cast(auth_data->id_token_listener_impl)); assert(env->ExceptionCheck() == false); - // Deleting our global references should trigger the FirebaseAuth class and - // FirebaseUser Java objects to be deleted. + // Clear the retained User object, which is used to support those deprecated + // Auth methods which return User pointer. + SetUserImpl(auth_data, nullptr); + + auth_data->deprecated_fields.user_internal_deprecated = nullptr; + + // This also deletes auth_data->deprecated_fields.user_internal_deprecated + // since User has ownership of the UserInternal allocation. + delete auth_data->deprecated_fields.user_deprecated; + auth_data->deprecated_fields.user_deprecated = nullptr; + + // Deleting our global references should trigger the FirebaseAuth class to be + // deleted. SetImplFromLocalRef(env, nullptr, &auth_data->listener_impl); SetImplFromLocalRef(env, nullptr, &auth_data->id_token_listener_impl); - SetImplFromLocalRef(env, nullptr, &auth_data->user_impl); SetImplFromLocalRef(env, nullptr, &auth_data->auth_impl); FIREBASE_ASSERT(g_initialized_count); @@ -342,7 +344,7 @@ static void ReadProviderResult( jobject result, FutureCallbackData* d, bool success, void* void_data) { auto data = static_cast(void_data); - JNIEnv* env = Env(d->auth_data); + JNIEnv* env = d->env; // `result` comes from the successfully completed Task in Java. If the Task // completed successfully, `result` should be valid. @@ -387,7 +389,8 @@ Future Auth::FetchProvidersForEmail( env->DeleteLocalRef(j_email); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, ReadProviderResult); + RegisterCallback(env, pending_result, handle, auth_data_->future_api_id, + &futures, ReadProviderResult); env->DeleteLocalRef(pending_result); } return MakeFuture(&futures, handle); @@ -395,22 +398,26 @@ Future Auth::FetchProvidersForEmail( Future Auth::SignInWithCustomToken_DEPRECATED(const char* token) { ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED); - JNIEnv* env = Env(auth_data_); + SafeFutureHandle future_handle = + auth_data_->future_impl.SafeAlloc( + kAuthFn_SignInWithCustomToken_DEPRECATED); + Future future = MakeFuture(&auth_data_->future_impl, future_handle); + JNIEnv* env = Env(auth_data_); jstring j_token = env->NewStringUTF(token); jobject pending_result = env->CallObjectMethod( AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInWithCustomToken), j_token); env->DeleteLocalRef(j_token); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - ReadUserFromSignInResult); + if (!CheckAndCompleteFutureOnError(env, &futures, future_handle)) { + RegisterCallbackWithAuthData(env, auth_data_, pending_result, future_handle, + auth_data_->future_api_id, + &auth_data_->future_impl, + ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } Future Auth::SignInWithCredential_DEPRECATED( @@ -430,8 +437,9 @@ Future Auth::SignInWithCredential_DEPRECATED( CredentialFromImpl(credential.impl_)); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - ReadUserFromSignInResult); + RegisterCallbackWithAuthData(env, auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, + ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } } @@ -440,26 +448,28 @@ Future Auth::SignInWithCredential_DEPRECATED( Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential& credential) { - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc( + const auto future_handle = auth_data_->future_impl.SafeAlloc( kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED); JNIEnv* env = Env(auth_data_); // If the credential itself is in an error state, don't try signing in. if (credential.error_code_ != kAuthErrorNone) { - futures.Complete(handle, credential.error_code_, - credential.error_message_.c_str()); + auth_data_->future_impl.Complete(future_handle, credential.error_code_, + credential.error_message_.c_str()); } else { jobject pending_result = env->CallObjectMethod( AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInWithCredential), CredentialFromImpl(credential.impl_)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, ReadSignInResult); + if (!CheckAndCompleteFutureOnError(env, &auth_data_->future_impl, + future_handle)) { + RegisterCallbackWithAuthData(env, auth_data_, pending_result, + future_handle, auth_data_->future_api_id, + &auth_data_->future_impl, ReadSignInResult); env->DeleteLocalRef(pending_result); } } - return MakeFuture(&futures, handle); + return MakeFuture(&auth_data_->future_impl, future_handle); } Future Auth::SignInWithProvider_DEPRECATED( @@ -478,8 +488,9 @@ Future Auth::SignInAnonymously_DEPRECATED() { AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInAnonymously)); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - ReadUserFromSignInResult); + RegisterCallbackWithAuthData(env, auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, + ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } @@ -511,8 +522,9 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED( env->DeleteLocalRef(j_password); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - ReadUserFromSignInResult); + RegisterCallbackWithAuthData(env, auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, + ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } @@ -521,16 +533,16 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED( Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( const char* email, const char* password) { - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc( + const auto future_handle = auth_data_->future_impl.SafeAlloc( kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED); if (!email || strlen(email) == 0 || !password || strlen(password) == 0) { - futures.Complete(handle, - (!email || strlen(email) == 0) ? kAuthErrorMissingEmail - : kAuthErrorMissingPassword, - kErrorEmptyEmailPassword); - return MakeFuture(&futures, handle); + auth_data_->future_impl.Complete(future_handle, + (!email || strlen(email) == 0) + ? kAuthErrorMissingEmail + : kAuthErrorMissingPassword, + kErrorEmptyEmailPassword); + return MakeFuture(&auth_data_->future_impl, future_handle); } JNIEnv* env = Env(auth_data_); @@ -543,12 +555,15 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( env->DeleteLocalRef(j_email); env->DeleteLocalRef(j_password); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - ReadUserFromSignInResult); + if (!CheckAndCompleteFutureOnError(env, &auth_data_->future_impl, + future_handle)) { + RegisterCallbackWithAuthData(env, auth_data_, pending_result, future_handle, + auth_data_->future_api_id, + &auth_data_->future_impl, + ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return MakeFuture(&auth_data_->future_impl, future_handle); } // It's safe to return a direct pointer to `current_user` because that class @@ -558,15 +573,12 @@ User* Auth::current_user_DEPRECATED() { if (!auth_data_) return nullptr; MutexLock lock(auth_data_->future_impl.mutex()); - // auth_data_->current_user should be available after Auth is created because - // persistent is loaded during the constructor of Android FirebaseAuth. - // This may change to make FirebaseAuth.getCurrentUser() to block and wait for - // persistent loading. However, it is safe to access auth_data_->current_user - // here since FirebaseAuth.getCurrentUser() (Android) is called in - // InitPlatformAuth(). - User* user = - auth_data_->user_impl == nullptr ? nullptr : &auth_data_->current_user; - return user; + if (auth_data_->deprecated_fields.user_deprecated == nullptr || + !auth_data_->deprecated_fields.user_deprecated->is_valid()) { + return nullptr; + } else { + return auth_data_->deprecated_fields.user_deprecated; + } } std::string Auth::language_code() const { @@ -612,7 +624,7 @@ void Auth::SignOut() { // Release our current user implementation in Java. MutexLock lock(auth_data_->future_impl.mutex()); - SetImplFromLocalRef(env, nullptr, &auth_data_->user_impl); + SetUserImpl(auth_data_, nullptr); } Future Auth::SendPasswordResetEmail(const char* email) { @@ -631,7 +643,8 @@ Future Auth::SendPasswordResetEmail(const char* email) { env->DeleteLocalRef(j_email); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); + RegisterCallback(env, pending_result, handle, auth_data_->future_api_id, + &futures, nullptr); env->DeleteLocalRef(pending_result); } return MakeFuture(&futures, handle); diff --git a/auth/src/android/common_android.cc b/auth/src/android/common_android.cc index f1f2587cea..0cfd44d594 100644 --- a/auth/src/android/common_android.cc +++ b/auth/src/android/common_android.cc @@ -472,7 +472,7 @@ void SetImplFromLocalRef(JNIEnv* env, jobject j_local, void** impl) { // Reads the `AuthResult` in `result` and initialize the `User*` in `void_data`. void ReadSignInResult(jobject result, FutureCallbackData* d, bool success, void* void_data) { - JNIEnv* env = Env(d->auth_data); + JNIEnv* env = d->env; // Update the currently signed-in user on success. // Note: `result` is only valid when success is true. @@ -485,7 +485,7 @@ void ReadSignInResult(jobject result, FutureCallbackData* d, // Update our pointer to the Android FirebaseUser that we're wrapping. // Note: Cannot call UpdateCurrentUser(d->auth_data) because the Java // Auth class has not been updated at this point. - SetImplFromLocalRef(env, j_user, &d->auth_data->user_impl); + SetUserImpl(d->auth_data, j_user); // Grab the additional user info too. // Additional user info is not guaranteed to exist, so could be nullptr. @@ -521,7 +521,7 @@ void ReadUserFromSignInResult(jobject result, FutureCallbackData* d, // Update our pointer to the Android FirebaseUser that we're wrapping. // Note: Cannot call UpdateCurrentUser(d->auth_data) because the Java // Auth class has not been updated at this point. - SetImplFromLocalRef(env, j_user, &d->auth_data->user_impl); + SetUserImpl(d->auth_data, j_user); } // Return a pointer to the current user, if the current user is valid. diff --git a/auth/src/android/common_android.h b/auth/src/android/common_android.h index 6cbe4ac9c0..6382b338a8 100644 --- a/auth/src/android/common_android.h +++ b/auth/src/android/common_android.h @@ -50,20 +50,143 @@ template struct FutureCallbackData { // During the callback, read `result` data from Java into the returned // C++ data in `d->future_data->Data()`. - typedef void ReadFutureResultFn(jobject result, FutureCallbackData* d, + typedef void ReadFutureResultFn(jobject result, + FutureCallbackData* future_callback_Data, bool success, void* void_data); - FutureCallbackData(const SafeFutureHandle& handle, AuthData* auth_data, + FutureCallbackData(JNIEnv* env, AuthData* auth_data, + const SafeFutureHandle& handle, + ReferenceCountedFutureImpl* future_impl, ReadFutureResultFn* future_data_read_fn) - : handle(handle), + : env(env), auth_data(auth_data), + handle(handle), + future_impl(future_impl), future_data_read_fn(future_data_read_fn) {} - SafeFutureHandle handle; + JNIEnv* env; AuthData* auth_data; + SafeFutureHandle handle; + ReferenceCountedFutureImpl* future_impl; ReadFutureResultFn* future_data_read_fn; }; +// Contains the interface between the public API and the underlying +// Android Java SDK FirebaseUser implemention. +class UserInternal { + public: + // Constructor + explicit UserInternal(JNIEnv* env, jobject android_user); + + // Copy constructor. + UserInternal(const UserInternal& user_internal); + + ~UserInternal(); + + // @deprecated + // + // Provides a mechanism for the deprecated auth-contained user object to + // update its underlying Android Java SDK FirebaseUser object. + void set_native_user_object_deprecated(jobject android_user); + + bool is_valid() const; + + Future GetToken(AuthData* auth_data, bool force_refresh); + Future GetTokenLastResult() const; + + Future UpdateEmail(const char* email); + Future UpdateEmailLastResult() const; + + std::vector provider_data() const; + const std::vector& provider_data_DEPRECATED(); + + Future UpdatePassword(const char* password); + Future UpdatePasswordLastResult() const; + + Future UpdateUserProfile(const User::UserProfile& profile); + Future UpdateUserProfileLastResult() const; + + Future SendEmailVerification(); + Future SendEmailVerificationLastResult() const; + + Future LinkWithCredential_DEPRECATED(AuthData* auth_data, + const Credential& credential); + Future LinkWithCredentialLastResult_DEPRECATED() const; + + Future LinkAndRetrieveDataWithCredential_DEPRECATED( + AuthData* auth_data_, const Credential& credential); + Future LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() + const; + + Future LinkWithProvider_DEPRECATED( + AuthData* auth_data, FederatedAuthProvider* provider); + Future LinkWithProviderLastResult_DEPRECATED() const; + + Future Unlink_DEPRECATED(AuthData* auth_data, const char* provider); + Future UnlinkLastResult_DEPRECATED() const; + + Future UpdatePhoneNumberCredential_DEPRECATED( + AuthData* auth_data, const Credential& credential); + Future UpdatePhoneNumberCredentialLastResult_DEPRECATED() const; + + Future Reload(); + Future ReloadLastResult() const; + + Future Reauthenticate(const Credential& credential); + Future ReauthenticateLastResult() const; + + Future ReauthenticateAndRetrieveData_DEPRECATED( + AuthData* auth_data, const Credential& credential); + Future ReauthenticateAndRetrieveDataLastResult_DEPRECATED() + const; + + Future ReauthenticateWithProvider_DEPRECATED( + AuthData* auth_data, FederatedAuthProvider* provider); + Future ReauthenticateWithProviderLastResult_DEPRECATED() const; + + Future Delete(AuthData* auth_data); + Future DeleteLastResult() const; + + UserMetadata metadata() const; + bool is_email_verified() const; + bool is_anonymous() const; + std::string uid() const; + std::string email() const; + std::string display_name() const; + std::string phone_number() const; + std::string photo_url() const; + std::string provider_id() const; + + private: + friend class firebase::auth::FederatedOAuthProvider; + friend class firebase::auth::User; + + void clear_user_infos(); + + // Android Java SDK Implementation of a FirebaseUser object. + jobject user_; + + // Pointer to the app's JNI environment context. + JNIEnv* env_; + + // Future data used to synchronize asynchronous calls. + FutureData future_data_; + + // Used to support older method invocation of provider_data_DEPRECATED(). + std::vector user_infos_; + + // Guard the creation and deletion of the vector of UserInfoInterface* + // allocations in provider_data_DEPRECATED(). + Mutex user_info_mutex_deprecated_; + + // Guard against changes to the user_ object. + Mutex user_mutex_; + + // Used to identify on-going futures in case we need to cancel them + // upon UserInternal destruction. + std::string future_api_id_; +}; + // The `ReadFutureResultFn` for `SignIn` APIs. // Reads the `AuthResult` in `result` and initialize the `User*` in `void_data`. void ReadSignInResult(jobject result, FutureCallbackData* d, @@ -112,18 +235,23 @@ inline JNIEnv* Env(AuthData* auth_data) { return auth_data->app->GetJNIEnv(); } // Delete the existing impl pointer global reference, if it already exists. void SetImplFromLocalRef(JNIEnv* env, jobject j_local, void** impl); +/// @deprecated +/// +/// Replace the platform-dependent FirebaseUser Android SDK object. +/// Note: this function is only used to support DEPRECATED methods which return +/// User*. This functionality should be removed when those deprecated methods +/// are removed. +inline void SetUserImpl(AuthData* _Nonnull auth_data, jobject j_user) { + auth_data->deprecated_fields.user_internal_deprecated + ->set_native_user_object_deprecated(j_user); +} + // Return the Java FirebaseAuth class from our platform-independent // representation. inline jobject AuthImpl(AuthData* auth_data) { return static_cast(auth_data->auth_impl); } -// Return the Java FirebaseUser class from our platform-independent -// representation. -inline jobject UserImpl(AuthData* auth_data) { - return static_cast(auth_data->user_impl); -} - // Return a platform-independent representation of Java's FirebaseUser class. inline void* ImplFromUser(jobject user) { return static_cast(user); } @@ -177,24 +305,25 @@ AuthError MapFutureCallbackResultToAuthError(JNIEnv* env, jobject result, template void FutureCallback(JNIEnv* env, jobject result, util::FutureResult result_code, const char* status_message, void* callback_data) { - FutureCallbackData* data = + FutureCallbackData* future_callback_data = static_cast*>(callback_data); bool success = false; const AuthError error = MapFutureCallbackResultToAuthError(env, result, result_code, &success); // Finish off the asynchronous call so that the caller can read it. - data->auth_data->future_impl.Complete( - data->handle, error, status_message, - [result, success, data](void* user_data) { - if (data->future_data_read_fn != nullptr) { - data->future_data_read_fn(result, data, success, user_data); + future_callback_data->future_impl->Complete( + future_callback_data->handle, error, status_message, + [result, success, future_callback_data](void* user_data) { + if (future_callback_data->future_data_read_fn != nullptr) { + future_callback_data->future_data_read_fn( + result, future_callback_data, success, user_data); } }); // Remove the callback structure that was allocated when the callback was // created in SetupFuture(). - delete data; - data = nullptr; + delete future_callback_data; + future_callback_data = nullptr; } // The function called by the Java thread when a result completes. @@ -203,7 +332,7 @@ void FederatedAuthProviderFutureCallback(JNIEnv* env, jobject result, util::FutureResult result_code, const char* status_message, void* callback_data) { - FutureCallbackData* data = + FutureCallbackData* future_callback_data = static_cast*>(callback_data); bool success = false; AuthError error = @@ -215,18 +344,19 @@ void FederatedAuthProviderFutureCallback(JNIEnv* env, jobject result, error = kAuthErrorInvalidProviderId; } // Finish off the asynchronous call so that the caller can read it. - data->auth_data->future_impl.Complete( - data->handle, error, status_message, - [result, success, data](void* user_data) { - if (data->future_data_read_fn != nullptr) { - data->future_data_read_fn(result, data, success, user_data); + future_callback_data->future_impl->Complete( + future_callback_data->handle, error, status_message, + [result, success, future_callback_data](void* user_data) { + if (future_callback_data->future_data_read_fn != nullptr) { + future_callback_data->future_data_read_fn( + result, future_callback_data, success, user_data); } }); // Remove the callback structure that was allocated when the callback was // created in SetupFuture(). - delete data; - data = nullptr; + delete future_callback_data; + future_callback_data = nullptr; } // Ensure `FutureCallback` gets called when `pending_result` completes. @@ -234,13 +364,29 @@ void FederatedAuthProviderFutureCallback(JNIEnv* env, jobject result, // data from Java, and then complete the Future for `handle`. template void RegisterCallback( - jobject pending_result, SafeFutureHandle handle, AuthData* auth_data, + JNIEnv* env, jobject pending_result, SafeFutureHandle handle, + const std::string& future_api_id, ReferenceCountedFutureImpl* future_impl, + typename FutureCallbackData::ReadFutureResultFn read_result_fn) { + // The FutureCallbackData structure is deleted in FutureCallback(). + util::RegisterCallbackOnTask( + env, pending_result, FutureCallback, + new FutureCallbackData(env, /*auth_data=*/nullptr, handle, future_impl, + read_result_fn), + future_api_id.c_str()); +} + +template +void RegisterCallbackWithAuthData( + JNIEnv* env, AuthData* auth_data, jobject pending_result, + SafeFutureHandle handle, const std::string& future_api_id, + ReferenceCountedFutureImpl* future_impl, typename FutureCallbackData::ReadFutureResultFn read_result_fn) { // The FutureCallbackData structure is deleted in FutureCallback(). util::RegisterCallbackOnTask( - Env(auth_data), pending_result, FutureCallback, - new FutureCallbackData(handle, auth_data, read_result_fn), - auth_data->future_api_id.c_str()); + env, pending_result, FutureCallback, + new FutureCallbackData(env, auth_data, handle, future_impl, + read_result_fn), + future_api_id.c_str()); } // Akin to RegisterCallback above, but has a special callback handler @@ -250,14 +396,17 @@ void RegisterCallback( // with the existing API behavior for other sign in events. template void RegisterFederatedAuthProviderCallback( - jobject pending_result, SafeFutureHandle handle, AuthData* auth_data, + JNIEnv* env, AuthData* auth_data, jobject pending_result, + SafeFutureHandle handle, const std::string& future_api_id, + ReferenceCountedFutureImpl* future_impl, typename FutureCallbackData::ReadFutureResultFn read_result_fn) { // The FutureCallbackData structure is deleted in // FederatedAuthProviderFutureCallback(). util::RegisterCallbackOnTask( - Env(auth_data), pending_result, FederatedAuthProviderFutureCallback, - new FutureCallbackData(handle, auth_data, read_result_fn), - auth_data->future_api_id.c_str()); + env, pending_result, FederatedAuthProviderFutureCallback, + new FutureCallbackData(env, auth_data, handle, future_impl, + read_result_fn), + future_api_id.c_str()); } // Checks if there was an error, and if so, completes the given future with the diff --git a/auth/src/android/credential_android.cc b/auth/src/android/credential_android.cc index e9512f9bf6..5b84e3ddcf 100644 --- a/auth/src/android/credential_android.cc +++ b/auth/src/android/credential_android.cc @@ -652,24 +652,24 @@ Future GameCenterAuthProvider::GetCredential() { // Game Center is not available on Android bool is_gamecenter_available_on_android = false; - auto future_api = GetCredentialFutureImpl(); - const auto handle = - future_api->SafeAlloc(kCredentialFn_GameCenterGetCredential); + ReferenceCountedFutureImpl* future_impl = GetCredentialFutureImpl(); + const auto future_handle = + future_impl->SafeAlloc(kCredentialFn_GameCenterGetCredential); - future_api->Complete(handle, kAuthErrorInvalidCredential, - "GameCenter is not supported on Android."); + future_impl->Complete(future_handle, kAuthErrorInvalidCredential, + "GameCenter is not supported on Android."); - FIREBASE_ASSERT_RETURN(MakeFuture(future_api, handle), + FIREBASE_ASSERT_RETURN(MakeFuture(future_impl, future_handle), is_gamecenter_available_on_android); - return MakeFuture(future_api, handle); + return MakeFuture(future_impl, future_handle); } // static Future GameCenterAuthProvider::GetCredentialLastResult() { - auto future_api = GetCredentialFutureImpl(); + ReferenceCountedFutureImpl* future_impl = GetCredentialFutureImpl(); auto last_result = - future_api->LastResult(kCredentialFn_GameCenterGetCredential); + future_impl->LastResult(kCredentialFn_GameCenterGetCredential); return static_cast&>(last_result); } @@ -1013,75 +1013,82 @@ Future FederatedOAuthProvider::SignIn(AuthData* auth_data) { assert(auth_data); JNIEnv* env = Env(auth_data); - ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = futures.SafeAlloc( + ReferenceCountedFutureImpl& future_impl = auth_data->future_impl; + const auto future_handle = future_impl.SafeAlloc( kAuthFn_SignInWithProvider_DEPRECATED, SignInResult()); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { jobject task = env->CallObjectMethod( AuthImpl(auth_data), auth_idp::GetMethodId(auth_idp::kStartActivityForSignInWithProvider), auth_data->app->activity(), oauthprovider); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterFederatedAuthProviderCallback(task, handle, auth_data, - ReadSignInResult); + + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { + RegisterFederatedAuthProviderCallback( + Env(auth_data), auth_data, task, future_handle, + auth_data->future_api_id, &auth_data->future_impl, ReadSignInResult); } env->DeleteLocalRef(task); } env->DeleteLocalRef(oauthprovider); - return MakeFuture(&futures, handle); + return MakeFuture(&future_impl, future_handle); } -Future FederatedOAuthProvider::Link(AuthData* auth_data) { - assert(auth_data); - JNIEnv* env = Env(auth_data); - ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = futures.SafeAlloc( +Future FederatedOAuthProvider::Link(AuthData* auth_data, + UserInternal* user_internal) { + ReferenceCountedFutureImpl& future_impl = + user_internal->future_data_.future_impl; + const auto future_handle = future_impl.SafeAlloc( kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - jobject task = env->CallObjectMethod( - UserImpl(auth_data), + if (!CheckAndCompleteFutureOnError(user_internal->env_, &future_impl, + future_handle)) { + jobject task = user_internal->env_->CallObjectMethod( + user_internal->user_, user_idp::GetMethodId(user_idp::kStartActivityForLinkWithProvider), auth_data->app->activity(), oauthprovider); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterFederatedAuthProviderCallback(task, handle, auth_data, - ReadSignInResult); + if (!CheckAndCompleteFutureOnError(user_internal->env_, &future_impl, + future_handle)) { + RegisterFederatedAuthProviderCallback( + Env(auth_data), auth_data, task, future_handle, + auth_data->future_api_id, &auth_data->future_impl, ReadSignInResult); } - env->DeleteLocalRef(task); + Env(auth_data)->DeleteLocalRef(task); } - env->DeleteLocalRef(oauthprovider); - return MakeFuture(&futures, handle); + user_internal->env_->DeleteLocalRef(oauthprovider); + return MakeFuture(&future_impl, future_handle); } Future FederatedOAuthProvider::Reauthenticate( - AuthData* auth_data) { - assert(auth_data); - JNIEnv* env = Env(auth_data); - ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = futures.SafeAlloc( + AuthData* auth_data, UserInternal* user_internal) { + ReferenceCountedFutureImpl& future_impl = + user_internal->future_data_.future_impl; + const auto future_handle = future_impl.SafeAlloc( kUserFn_ReauthenticateWithProvider_DEPRECATED, SignInResult()); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - jobject task = env->CallObjectMethod( - UserImpl(auth_data), + if (!CheckAndCompleteFutureOnError(user_internal->env_, &future_impl, + future_handle)) { + jobject task = user_internal->env_->CallObjectMethod( + user_internal->user_, user_idp::GetMethodId( user_idp::kStartActivityForReauthenticateWithProvider), auth_data->app->activity(), oauthprovider); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterFederatedAuthProviderCallback(task, handle, auth_data, - ReadSignInResult); + if (!CheckAndCompleteFutureOnError(user_internal->env_, &future_impl, + future_handle)) { + RegisterFederatedAuthProviderCallback( + Env(auth_data), auth_data, task, future_handle, + auth_data->future_api_id, &auth_data->future_impl, ReadSignInResult); } - env->DeleteLocalRef(task); + user_internal->env_->DeleteLocalRef(task); } - env->DeleteLocalRef(oauthprovider); - return MakeFuture(&futures, handle); + user_internal->env_->DeleteLocalRef(oauthprovider); + return MakeFuture(&future_impl, future_handle); } } // namespace auth diff --git a/auth/src/android/user_android.cc b/auth/src/android/user_android.cc index 2df7db018e..55212748ef 100644 --- a/auth/src/android/user_android.cc +++ b/auth/src/android/user_android.cc @@ -128,7 +128,7 @@ METHOD_LOOKUP_DEFINITION( "com/google/firebase/auth/UserProfileChangeRequest$Builder", USER_PROFILE_BUILDER_METHODS) -bool CacheUserMethodIds(JNIEnv* env, jobject activity) { +bool CacheUserMethodIds(JNIEnv *env, jobject activity) { return phonecredential::CacheMethodIds(env, activity) && tokenresult::CacheMethodIds(env, activity) && user::CacheMethodIds(env, activity) && @@ -137,7 +137,7 @@ bool CacheUserMethodIds(JNIEnv* env, jobject activity) { userprofilebuilder::CacheMethodIds(env, activity); } -void ReleaseUserClasses(JNIEnv* env) { +void ReleaseUserClasses(JNIEnv *env) { phonecredential::ReleaseClass(env); tokenresult::ReleaseClass(env); user::ReleaseClass(env); @@ -146,137 +146,391 @@ void ReleaseUserClasses(JNIEnv* env) { userprofilebuilder::ReleaseClass(env); } +/// +/// AndroidWrappedUserInfo Class. +/// Queries data out of Java Android SDK UserInfo objects. +/// enum PropertyType { kPropertyTypeString, kPropertyTypeUri }; -static std::string GetUserProperty(AuthData* auth_data, jobject impl, - userinfo::Method method_id, - PropertyType type = kPropertyTypeString) { - JNIEnv* env = Env(auth_data); - jobject property = - impl ? env->CallObjectMethod(impl, userinfo::GetMethodId(method_id)) - : nullptr; - if (firebase::util::CheckAndClearJniExceptions(env) || !property) { - return std::string(); +class AndroidWrappedUserInfo : public UserInfoInterface { + public: + AndroidWrappedUserInfo(JNIEnv *env, jobject user_info) + : env_(env), user_info_(user_info) { + // Convert `user_info` to a global reference. + user_info_ = env_->NewGlobalRef(user_info); + env->DeleteLocalRef(user_info); + } + + virtual ~AndroidWrappedUserInfo() { + // Delete global reference. + env_->DeleteGlobalRef(user_info_); + user_info_ = nullptr; + env_ = nullptr; + } + + std::string uid() const override { + return GetUserProperty(userinfo::kGetUid); + } + + std::string email() const override { + return GetUserProperty(userinfo::kGetEmail); + } + + std::string display_name() const override { + return GetUserProperty(userinfo::kGetDisplayName); + } + + std::string phone_number() const override { + return GetUserProperty(userinfo::kGetPhoneNumber); + } + + std::string photo_url() const override { + return GetUserProperty(userinfo::kGetPhotoUrl, kPropertyTypeUri); + } + + std::string provider_id() const override { + return GetUserProperty(userinfo::kGetProviderId); + } + + private: + std::string GetUserProperty(userinfo::Method method_id, + PropertyType type = kPropertyTypeString) const { + jobject property = user_info_ + ? env_->CallObjectMethod( + user_info_, userinfo::GetMethodId(method_id)) + : nullptr; + if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + return std::string(); + } + if (type == kPropertyTypeUri) { + return JniUriToString(env_, property); + } else { + // type == kPropertyTypeString + return JniStringToString(env_, property); + } + } + + /// The app's JNIEnv context. Required to invoke Java API methods. + JNIEnv *env_; + + /// Pointer to the main class. + /// Needed for context in implementation of virtuals. + jobject user_info_; +}; + +/// +/// User Class +/// Platform specific implementation of UserInternal. +/// +User::User(AuthData *auth_data, UserInternal *user_internal) { + assert(auth_data); + if (user_internal == nullptr) { + // Create an invalid user internal. + // This will return is_valid() false, and operations will fail. + user_internal_ = new UserInternal(Env(auth_data), nullptr); + } else { + user_internal_ = user_internal; } - if (type == kPropertyTypeUri) { - return JniUriToString(env, property); + auth_data_ = auth_data; +} + +User::~User() { + delete user_internal_; + user_internal_ = nullptr; + auth_data_ = nullptr; +} + +User &User::operator=(const User &user) { + assert(user_internal_); + delete user_internal_; + if (user.user_internal_ != nullptr) { + user_internal_ = + new UserInternal(user.user_internal_->env_, user.user_internal_->user_); } else { - // type == kPropertyTypeString - return JniStringToString(env, property); + user_internal_ = new UserInternal(Env(user.auth_data_), nullptr); } + auth_data_ = user.auth_data_; + return *this; } -static std::string GetUID(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetUid); +bool User::is_valid() const { + assert(user_internal_); + return user_internal_->is_valid(); } -static std::string GetEmail(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetEmail); +Future User::GetToken(bool force_refresh) { + assert(user_internal_); + return user_internal_->GetToken(auth_data_, force_refresh); } -static std::string GetDisplayName(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetDisplayName); +std::vector User::provider_data() const { + assert(user_internal_); + return user_internal_->provider_data(); } -static std::string GetPhoneNumber(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetPhoneNumber); +const std::vector &User::provider_data_DEPRECATED() { + assert(user_internal_); + return user_internal_->provider_data_DEPRECATED(); } -static std::string GetPhotoUrl(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetPhotoUrl, - kPropertyTypeUri); +Future User::UpdateEmail(const char *email) { + assert(user_internal_); + return user_internal_->UpdateEmail(email); } -static std::string GetProviderId(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetProviderId); +Future User::UpdateEmailLastResult() const { + assert(user_internal_); + return user_internal_->UpdateEmailLastResult(); } -User::~User() {} +Future User::UpdatePassword(const char *password) { + assert(user_internal_); + return user_internal_->UpdatePassword(password); +} + +Future User::UpdatePasswordLastResult() const { + assert(user_internal_); + return user_internal_->UpdatePasswordLastResult(); +} + +Future User::Reauthenticate(const Credential &credential) { + assert(user_internal_); + return user_internal_->Reauthenticate(credential); +} + +Future User::ReauthenticateLastResult() const { + assert(user_internal_); + return user_internal_->ReauthenticateLastResult(); +} + +Future User::ReauthenticateAndRetrieveData_DEPRECATED( + const Credential &credential) { + assert(user_internal_); + return user_internal_->ReauthenticateAndRetrieveData_DEPRECATED(auth_data_, + credential); +} + +Future User::ReauthenticateAndRetrieveDataLastResult_DEPRECATED() + const { + assert(user_internal_); + return user_internal_->ReauthenticateAndRetrieveDataLastResult_DEPRECATED(); +} + +Future User::ReauthenticateWithProvider_DEPRECATED( + FederatedAuthProvider *provider) const { + assert(user_internal_); + return user_internal_->ReauthenticateWithProvider_DEPRECATED(auth_data_, + provider); +} + +Future User::SendEmailVerification() { + assert(user_internal_); + return user_internal_->SendEmailVerification(); +} + +Future User::SendEmailVerificationLastResult() const { + assert(user_internal_); + return user_internal_->SendEmailVerificationLastResult(); +} + +Future User::UpdateUserProfile(const UserProfile &profile) { + assert(user_internal_); + return user_internal_->UpdateUserProfile(profile); +} + +Future User::UpdateUserProfileLastResult() const { + assert(user_internal_); + return user_internal_->UpdateUserProfileLastResult(); +} + +Future User::LinkWithCredential_DEPRECATED( + const Credential &credential) { + assert(user_internal_); + return user_internal_->LinkWithCredential_DEPRECATED(auth_data_, credential); +} + +Future User::LinkWithCredentialLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_->LinkWithCredentialLastResult_DEPRECATED(); +} + +Future User::LinkAndRetrieveDataWithCredential_DEPRECATED( + const Credential &credential) { + assert(user_internal_); + return user_internal_->LinkAndRetrieveDataWithCredential_DEPRECATED( + auth_data_, credential); +} + +Future +User::LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_ + ->LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED(); +} + +Future User::LinkWithProvider_DEPRECATED( + FederatedAuthProvider *provider) { + assert(user_internal_); + return user_internal_->LinkWithProvider_DEPRECATED(auth_data_, provider); +} + +Future User::Unlink_DEPRECATED(const char *provider) { + assert(user_internal_); + return user_internal_->Unlink_DEPRECATED(auth_data_, provider); +} + +Future User::UnlinkLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_->UnlinkLastResult_DEPRECATED(); +} + +Future User::UpdatePhoneNumberCredential_DEPRECATED( + const Credential &credential) { + assert(user_internal_); + return user_internal_->UpdatePhoneNumberCredential_DEPRECATED(auth_data_, + credential); +} + +Future User::UpdatePhoneNumberCredentialLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_->UpdatePhoneNumberCredentialLastResult_DEPRECATED(); +} + +Future User::Reload() { + assert(user_internal_); + return user_internal_->Reload(); +} + +Future User::ReloadLastResult() const { + assert(user_internal_); + return user_internal_->ReloadLastResult(); +} + +Future User::Delete() { + assert(user_internal_); + return user_internal_->Delete(auth_data_); +} + +Future User::DeleteLastResult() const { + assert(user_internal_); + return user_internal_->DeleteLastResult(); +} + +UserMetadata User::metadata() const { + assert(user_internal_); + return user_internal_->metadata(); +} + +bool User::is_email_verified() const { + assert(user_internal_); + return user_internal_->is_email_verified(); +} + +bool User::is_anonymous() const { + assert(user_internal_); + return user_internal_->is_anonymous(); +} std::string User::uid() const { - return ValidUser(auth_data_) ? GetUID(auth_data_, UserImpl(auth_data_)) : ""; + assert(user_internal_); + return user_internal_->uid(); } std::string User::email() const { - return ValidUser(auth_data_) ? GetEmail(auth_data_, UserImpl(auth_data_)) - : ""; + assert(user_internal_); + return user_internal_->email(); } std::string User::display_name() const { - return ValidUser(auth_data_) - ? GetDisplayName(auth_data_, UserImpl(auth_data_)) - : ""; -} - -std::string User::phone_number() const { - return ValidUser(auth_data_) - ? GetPhoneNumber(auth_data_, UserImpl(auth_data_)) - : ""; + assert(user_internal_); + return user_internal_->display_name(); } std::string User::photo_url() const { - return ValidUser(auth_data_) ? GetPhotoUrl(auth_data_, UserImpl(auth_data_)) - : ""; + assert(user_internal_); + return user_internal_->photo_url(); } std::string User::provider_id() const { - return ValidUser(auth_data_) ? GetProviderId(auth_data_, UserImpl(auth_data_)) - : ""; + assert(user_internal_); + return user_internal_->provider_id(); } -class AndroidWrappedUserInfo : public UserInfoInterface { - public: - AndroidWrappedUserInfo(AuthData* auth_data, jobject user_info) - : auth_data_(auth_data), user_info_(user_info) { - // Convert `user_info` to a global reference. - JNIEnv* env = Env(auth_data_); - user_info_ = env->NewGlobalRef(user_info); - env->DeleteLocalRef(user_info); - } +std::string User::phone_number() const { + assert(user_internal_); + return user_internal_->phone_number(); +} - virtual ~AndroidWrappedUserInfo() { - // Delete global reference. - JNIEnv* env = Env(auth_data_); - env->DeleteGlobalRef(user_info_); - user_info_ = nullptr; - } +/// +/// UserInternal Class +/// +void assign_future_id(UserInternal *user_internal, std::string *future_api_id) { + static const char *kApiIdentifier = "UserInternal"; + future_api_id->reserve(strlen(kApiIdentifier) + + 16 /* hex characters in the pointer */ + + 1 /* null terminator */); + snprintf(&((*future_api_id)[0]), future_api_id->capacity(), "%s0x%016llx", + kApiIdentifier, + static_cast( // NOLINT + reinterpret_cast(user_internal))); +} - std::string uid() const override { return GetUID(auth_data_, user_info_); } +UserInternal::UserInternal(JNIEnv *env, jobject user) + : env_(env), user_(user), future_data_(kUserFnCount) { + assign_future_id(this, &future_api_id_); +} - std::string email() const override { - return GetEmail(auth_data_, user_info_); - } +UserInternal::UserInternal(const UserInternal &user_internal) + : env_(user_internal.env_), + user_(user_internal.user_), + future_data_(kUserFnCount) { + assign_future_id(this, &future_api_id_); +} - std::string display_name() const override { - return GetDisplayName(auth_data_, user_info_); +UserInternal::~UserInternal() { + util::CancelCallbacks(env_, future_api_id_.c_str()); + + env_->DeleteGlobalRef(user_); + env_ = nullptr; + user_ = nullptr; + + { + MutexLock user_info_lock(user_info_mutex_deprecated_); + clear_user_infos(); } - std::string phone_number() const override { - return GetPhoneNumber(auth_data_, user_info_); + // Make sure we don't have any pending futures in flight before we disappear. + while (!future_data_.future_impl.IsSafeToDelete()) { + internal::Sleep(100); } +} - std::string photo_url() const override { - return GetPhotoUrl(auth_data_, user_info_); +void UserInternal::set_native_user_object_deprecated(jobject user) { + MutexLock user_info_lock(user_mutex_); + if (user_ != nullptr) { + env_->DeleteGlobalRef(user_); } - std::string provider_id() const override { - return GetProviderId(auth_data_, user_info_); + if (user != nullptr) { + user = env_->NewGlobalRef(user); } + user_ = user; +} - private: - /// Pointer to the main class. - /// Needed for context in implementation of virtuals. - AuthData* auth_data_; +bool UserInternal::is_valid() const { return user_ != nullptr; } - /// Pointer to the main class. - /// Needed for context in implementation of virtuals. - jobject user_info_; -}; +void UserInternal::clear_user_infos() { + for (size_t i = 0; i < user_infos_.size(); ++i) { + delete user_infos_[i]; + user_infos_[i] = nullptr; + } + user_infos_.clear(); +} -void ReadTokenResult(jobject result, FutureCallbackData* d, - bool success, void* void_data) { - auto data = static_cast(void_data); - JNIEnv* env = Env(d->auth_data); +void ReadTokenResult(jobject result, FutureCallbackData *d, + bool success, void *void_data) { + auto data = static_cast(void_data); + JNIEnv *env = d->env; // `result` is of type GetTokenResult when `success` is true. if (success) { @@ -295,425 +549,706 @@ void ReadTokenResult(jobject result, FutureCallbackData* d, } } -Future User::GetToken(bool force_refresh) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::GetToken(AuthData *auth_data, + bool force_refresh) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_GetToken, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, + &future_data_, ""); + } else if (nullptr == auth_data) { + return CreateAndCompleteFuture(kUserFn_GetToken, kAuthErrorFailure, + "Internal AuthData nullptr", &future_data_, + ""); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_GetToken); - JNIEnv* env = Env(auth_data_); - auth_data_->SetExpectIdTokenListenerCallback(force_refresh); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kToken), force_refresh); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_GetToken); + Future future = + MakeFuture(&future_data_.future_impl, future_handle); + + auth_data->SetExpectIdTokenListenerCallback(force_refresh); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, ReadTokenResult); - env->DeleteLocalRef(pending_result); + jobject pending_result = env_->CallObjectMethod( + user_, user::GetMethodId(user::kToken), force_refresh); + + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallbackWithAuthData(env_, auth_data, pending_result, future_handle, + future_api_id_, &future_data_.future_impl, + ReadTokenResult); + env_->DeleteLocalRef(pending_result); } else { // If the method failed for some reason, clear the expected callback. - auth_data_->SetExpectIdTokenListenerCallback(false); + auth_data->SetExpectIdTokenListenerCallback(false); } - return MakeFuture(&futures, handle); + return future; } -const std::vector& User::provider_data() const { - ClearUserInfos(auth_data_); +std::vector UserInternal::provider_data() const { + std::vector local_user_infos; + if (is_valid()) { + const jobject list = + env_->CallObjectMethod(user_, user::GetMethodId(user::kProviderData)); + assert(env_->ExceptionCheck() == false); - if (ValidUser(auth_data_)) { - JNIEnv* env = Env(auth_data_); + if (list != nullptr) { + const int num_providers = + env_->CallIntMethod(list, util::list::GetMethodId(util::list::kSize)); + assert(env_->ExceptionCheck() == false); + local_user_infos.resize(num_providers); + for (int i = 0; i < num_providers; ++i) { + // user_info is converted to a global reference in + // AndroidWrappedUserInfo() and the local reference is released. + jobject user_info = env_->CallObjectMethod( + list, util::list::GetMethodId(util::list::kGet), i); + assert(env_->ExceptionCheck() == false); + local_user_infos[i] = AndroidWrappedUserInfo(env_, user_info); + } + env_->DeleteLocalRef(list); + } + } + return local_user_infos; +} + +const std::vector + &UserInternal::provider_data_DEPRECATED() { + MutexLock user_info_lock(user_info_mutex_deprecated_); + clear_user_infos(); + if (is_valid()) { // getProviderData returns `List` - const jobject list = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kProviderData)); - assert(env->ExceptionCheck() == false); + const jobject list = + env_->CallObjectMethod(user_, user::GetMethodId(user::kProviderData)); + assert(env_->ExceptionCheck() == false); - // Copy the list into auth_data_->user_infos. + // Copy the list into user_infos_. if (list != nullptr) { const int num_providers = - env->CallIntMethod(list, util::list::GetMethodId(util::list::kSize)); - assert(env->ExceptionCheck() == false); - auth_data_->user_infos.resize(num_providers); + env_->CallIntMethod(list, util::list::GetMethodId(util::list::kSize)); + assert(env_->ExceptionCheck() == false); + user_infos_.resize(num_providers); for (int i = 0; i < num_providers; ++i) { // user_info is converted to a global reference in // AndroidWrappedUserInfo() and the local reference is released. - jobject user_info = env->CallObjectMethod( + jobject user_info = env_->CallObjectMethod( list, util::list::GetMethodId(util::list::kGet), i); - assert(env->ExceptionCheck() == false); - auth_data_->user_infos[i] = - new AndroidWrappedUserInfo(auth_data_, user_info); + assert(env_->ExceptionCheck() == false); + user_infos_[i] = new AndroidWrappedUserInfo(env_, user_info); } - env->DeleteLocalRef(list); + env_->DeleteLocalRef(list); } } - // Return a reference to our internally-backed values. - return auth_data_->user_infos; + return user_infos_; } -Future User::UpdateEmail(const char* email) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdateEmail(const char *email) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_UpdateEmail, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, + &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdateEmail); - JNIEnv* env = Env(auth_data_); - - jstring j_email = env->NewStringUTF(email); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kUpdateEmail), j_email); - env->DeleteLocalRef(j_email); - - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); - env->DeleteLocalRef(pending_result); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_UpdateEmail); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + jstring j_email = env_->NewStringUTF(email); + jobject pending_result = env_->CallObjectMethod( + user_, user::GetMethodId(user::kUpdateEmail), j_email); + env_->DeleteLocalRef(j_email); + + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallback(env_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); + env_->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -Future User::UpdatePassword(const char* password) { - if (!ValidUser(auth_data_)) { - return Future(); - } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdatePassword); - JNIEnv* env = Env(auth_data_); - - jstring j_password = env->NewStringUTF(password); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kUpdatePassword), - j_password); - env->DeleteLocalRef(j_password); +Future UserInternal::UpdateEmailLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_UpdateEmail)); +} - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); - env->DeleteLocalRef(pending_result); +Future UserInternal::UpdatePassword(const char *password) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture( + kUserFn_UpdatePassword, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - return MakeFuture(&futures, handle); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_UpdatePassword); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + jstring j_password = env_->NewStringUTF(password); + jobject pending_result = env_->CallObjectMethod( + user_, user::GetMethodId(user::kUpdatePassword), j_password); + env_->DeleteLocalRef(j_password); + + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallback(env_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); + env_->DeleteLocalRef(pending_result); + } + return future; +} + +Future UserInternal::UpdatePasswordLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_UpdatePassword)); } -Future User::UpdateUserProfile(const UserProfile& profile) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdateUserProfile(const User::UserProfile &profile) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture( + kUserFn_UpdateUserProfile, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdateUserProfile); - JNIEnv* env = Env(auth_data_); + + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_UpdateUserProfile); + Future future = MakeFuture(&future_data_.future_impl, future_handle); AuthError error = kAuthErrorNone; std::string exception_error_message; - jobject j_user_profile_builder = env->NewObject( + jobject j_user_profile_builder = env_->NewObject( userprofilebuilder::GetClass(), userprofilebuilder::GetMethodId(userprofilebuilder::kConstructor)); - // Painfully call UserProfileChangeRequest.Builder.setDisplayName. + // Call UserProfileChangeRequest.Builder.setDisplayName. if (profile.display_name != nullptr) { - jstring j_display_name = env->NewStringUTF(profile.display_name); - jobject j_builder_discard = env->CallObjectMethod( + jstring j_display_name = env_->NewStringUTF(profile.display_name); + jobject j_builder_discard = env_->CallObjectMethod( j_user_profile_builder, userprofilebuilder::GetMethodId(userprofilebuilder::kSetDisplayName), j_display_name); - error = CheckAndClearJniAuthExceptions(env, &exception_error_message); + error = CheckAndClearJniAuthExceptions(env_, &exception_error_message); if (j_builder_discard) { - env->DeleteLocalRef(j_builder_discard); + env_->DeleteLocalRef(j_builder_discard); } - env->DeleteLocalRef(j_display_name); + env_->DeleteLocalRef(j_display_name); } - // Extra painfully call UserProfileChangeRequest.Builder.setPhotoUri. + // Call UserProfileChangeRequest.Builder.setPhotoUri. if (error == kAuthErrorNone && profile.photo_url != nullptr) { - jobject j_uri = CharsToJniUri(env, profile.photo_url); - jobject j_builder_discard = env->CallObjectMethod( + jobject j_uri = CharsToJniUri(env_, profile.photo_url); + jobject j_builder_discard = env_->CallObjectMethod( j_user_profile_builder, userprofilebuilder::GetMethodId(userprofilebuilder::kSetPhotoUri), j_uri); - error = CheckAndClearJniAuthExceptions(env, &exception_error_message); + error = CheckAndClearJniAuthExceptions(env_, &exception_error_message); if (j_builder_discard) { - env->DeleteLocalRef(j_builder_discard); + env_->DeleteLocalRef(j_builder_discard); } - env->DeleteLocalRef(j_uri); + env_->DeleteLocalRef(j_uri); } jobject j_user_profile_request = nullptr; if (error == kAuthErrorNone) { // Call UserProfileChangeRequest.Builder.build. - j_user_profile_request = env->CallObjectMethod( + j_user_profile_request = env_->CallObjectMethod( j_user_profile_builder, userprofilebuilder::GetMethodId(userprofilebuilder::kBuild)); - error = CheckAndClearJniAuthExceptions(env, &exception_error_message); + error = CheckAndClearJniAuthExceptions(env_, &exception_error_message); } if (error == kAuthErrorNone) { // Call FirebaseUser.updateProfile. - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kUpdateUserProfile), + jobject pending_result = env_->CallObjectMethod( + user_, user::GetMethodId(user::kUpdateUserProfile), j_user_profile_request); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); - env->DeleteLocalRef(pending_result); + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallback(env_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); + env_->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } else { - futures.Complete(handle, error, exception_error_message.c_str()); + future_data_.future_impl.Complete(future_handle, error, + exception_error_message.c_str()); } if (j_user_profile_request) { - env->DeleteLocalRef(j_user_profile_request); + env_->DeleteLocalRef(j_user_profile_request); } - env->DeleteLocalRef(j_user_profile_builder); - return MakeFuture(&futures, handle); + env_->DeleteLocalRef(j_user_profile_builder); + return future; +} + +Future UserInternal::UpdateUserProfileLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_UpdateUserProfile)); } -Future User::LinkWithCredential_DEPRECATED( - const Credential& credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::SendEmailVerification() { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture( + kUserFn_SendEmailVerification, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); + } + + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_SendEmailVerification); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + jobject pending_result = env_->CallObjectMethod( + user_, user::GetMethodId(user::kSendEmailVerification)); + + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallback(env_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); + env_->DeleteLocalRef(pending_result); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kUserFn_LinkWithCredential_DEPRECATED); - JNIEnv* env = Env(auth_data_); + return future; +} - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kLinkWithCredential), +Future UserInternal::SendEmailVerificationLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_SendEmailVerification)); +} + +Future UserInternal::LinkWithCredential_DEPRECATED( + AuthData *auth_data, const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_LinkWithCredential_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, (User *)nullptr); + return future; + } + + jobject pending_result = env_->CallObjectMethod( + user_, user::GetMethodId(user::kLinkWithCredential), CredentialFromImpl(credential.impl_)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - ReadUserFromSignInResult); - env->DeleteLocalRef(pending_result); + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallbackWithAuthData(env_, auth_data, pending_result, future_handle, + future_api_id_, &future_data_.future_impl, + ReadUserFromSignInResult); + env_->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -Future User::LinkAndRetrieveDataWithCredential( - const Credential& credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::LinkWithCredentialLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult( + kUserFn_LinkWithCredential_DEPRECATED)); +} + +Future UserInternal::LinkAndRetrieveDataWithCredential_DEPRECATED( + AuthData *auth_data, const Credential &credential) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED); + Future future = + MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, SignInResult()); + return future; } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc( - kUserFn_LinkAndRetrieveDataWithCredential); - JNIEnv* env = Env(auth_data_); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kLinkWithCredential), + jobject pending_result = env_->CallObjectMethod( + user_, user::GetMethodId(user::kLinkWithCredential), CredentialFromImpl(credential.impl_)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, ReadSignInResult); - env->DeleteLocalRef(pending_result); + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallbackWithAuthData(env_, auth_data, pending_result, future_handle, + future_api_id_, &future_data_.future_impl, + ReadSignInResult); + env_->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -Future User::LinkWithProvider_DEPRECATED( - FederatedAuthProvider* provider) const { - FIREBASE_ASSERT_RETURN(Future(), provider); - return provider->Link(auth_data_); +Future +UserInternal::LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult( + kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED)); } -Future User::Unlink_DEPRECATED(const char* provider) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::LinkWithProvider_DEPRECATED( + AuthData *auth_data, FederatedAuthProvider *provider) { + if (!is_valid() || provider == nullptr) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_LinkWithProvider_DEPRECATED); + Future future = + MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, SignInResult()); + } else { + CompleteFuture(kAuthErrorInvalidParameter, + kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } + return future; } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Unlink_DEPRECATED); - JNIEnv* env = Env(auth_data_); + return provider->Link(auth_data, this); +} - jstring j_provider = env->NewStringUTF(provider); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kUnlink), j_provider); - env->DeleteLocalRef(j_provider); +Future UserInternal::Unlink_DEPRECATED(AuthData *auth_data, + const char *provider) { + MutexLock user_info_lock(user_mutex_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_Unlink_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, (User *)nullptr); + return future; + } - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - ReadUserFromSignInResult); - env->DeleteLocalRef(pending_result); + jstring j_provider = env_->NewStringUTF(provider); + jobject pending_result = env_->CallObjectMethod( + user_, user::GetMethodId(user::kUnlink), j_provider); + env_->DeleteLocalRef(j_provider); + + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallbackWithAuthData(env_, auth_data, pending_result, future_handle, + future_api_id_, &future_data_.future_impl, + ReadUserFromSignInResult); + env_->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; +} + +Future UserInternal::UnlinkLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_Unlink_DEPRECATED)); } -Future User::UpdatePhoneNumberCredential_DEPRECATED( - const Credential& credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdatePhoneNumberCredential_DEPRECATED( + AuthData *auth_data, const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_UpdatePhoneNumberCredential_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, (User *)nullptr); + return future; } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kUserFn_UpdatePhoneNumberCredential_DEPRECATED); - JNIEnv* env = Env(auth_data_); jobject j_credential = CredentialFromImpl(credential.impl_); - if (env->IsInstanceOf(j_credential, phonecredential::GetClass())) { - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), - user::GetMethodId(user::kUpdatePhoneNumberCredential), j_credential); - - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - ReadUserFromSignInResult); - env->DeleteLocalRef(pending_result); + if (env_->IsInstanceOf(j_credential, phonecredential::GetClass())) { + jobject pending_result = env_->CallObjectMethod( + user_, user::GetMethodId(user::kUpdatePhoneNumberCredential), + j_credential); + + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallbackWithAuthData( + env_, auth_data, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadUserFromSignInResult); + env_->DeleteLocalRef(pending_result); } } else { - futures.Complete(handle, kAuthErrorInvalidCredential, - "Credential is not a phone credential."); + CompleteFuture(kAuthErrorInvalidCredential, kInvalidCredentialErrorMessage, + future_handle, &future_data_, (User *)nullptr); } - return MakeFuture(&futures, handle); + return future; } -Future User::Reload() { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdatePhoneNumberCredentialLastResult_DEPRECATED() + const { + return static_cast &>( + future_data_.future_impl.LastResult( + kUserFn_UpdatePhoneNumberCredential_DEPRECATED)); +} + +Future UserInternal::Reload() { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_Reload, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, + &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Reload); - JNIEnv* env = Env(auth_data_); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kReload)); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_Reload); + Future future = MakeFuture(&future_data_.future_impl, future_handle); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); - env->DeleteLocalRef(pending_result); + jobject pending_result = + env_->CallObjectMethod(user_, user::GetMethodId(user::kReload)); + + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallback(env_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); + env_->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; +} + +Future UserInternal::ReloadLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_Reload)); } -Future User::Reauthenticate(const Credential& credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::Reauthenticate(const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture( + kUserFn_Reauthenticate, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Reauthenticate); - JNIEnv* env = Env(auth_data_); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kReauthenticate), - CredentialFromImpl(credential.impl_)); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_Reload); + Future future = MakeFuture(&future_data_.future_impl, future_handle); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); - env->DeleteLocalRef(pending_result); + jobject pending_result = + env_->CallObjectMethod(user_, user::GetMethodId(user::kReauthenticate), + CredentialFromImpl(credential.impl_)); + + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallback(env_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); + env_->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -Future User::ReauthenticateAndRetrieveData_DEPRECATED( - const Credential& credential) { - if (!ValidUser(auth_data_)) { - return Future(); - } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc( - kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); - JNIEnv* env = Env(auth_data_); - - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), - user::GetMethodId(user::kReauthenticateAndRetrieveData), - CredentialFromImpl(credential.impl_)); +Future UserInternal::ReauthenticateLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_Reauthenticate)); +} - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, ReadSignInResult); - env->DeleteLocalRef(pending_result); +Future UserInternal::ReauthenticateAndRetrieveData_DEPRECATED( + AuthData *auth_data, const Credential &credential) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); + Future future = + MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, SignInResult()); + return future; } - return MakeFuture(&futures, handle); -} -Future User::ReauthenticateWithProvider_DEPRECATED( - FederatedAuthProvider* provider) const { - FIREBASE_ASSERT_RETURN(Future(), provider); - return provider->Reauthenticate(auth_data_); -} + jobject pending_result = env_->CallObjectMethod( + user_, user::GetMethodId(user::kReauthenticateAndRetrieveData), + CredentialFromImpl(credential.impl_)); -Future User::SendEmailVerification() { - if (!ValidUser(auth_data_)) { - return Future(); + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallbackWithAuthData(env_, auth_data, pending_result, future_handle, + future_api_id_, &future_data_.future_impl, + ReadSignInResult); + env_->DeleteLocalRef(pending_result); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_SendEmailVerification); - JNIEnv* env = Env(auth_data_); + return future; +} - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kSendEmailVerification)); +Future +UserInternal::ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult( + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED)); +} - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); - env->DeleteLocalRef(pending_result); +Future UserInternal::ReauthenticateWithProvider_DEPRECATED( + AuthData *auth_data, FederatedAuthProvider *provider) { + if (!is_valid() || provider == nullptr) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_ReauthenticateWithProvider_DEPRECATED); + Future future = + MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, SignInResult()); + } else { + CompleteFuture(kAuthErrorInvalidParameter, + kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } + return future; } - return MakeFuture(&futures, handle); + return provider->Reauthenticate(auth_data, this); } -Future User::Delete() { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::Delete(AuthData *auth_data) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_Delete, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, + &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Delete); - JNIEnv* env = Env(auth_data_); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kDelete)); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_Reload); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + jobject pending_result = + env_->CallObjectMethod(user_, user::GetMethodId(user::kDelete)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - [](jobject result, FutureCallbackData* d, - bool success, void* void_data) { + if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + future_handle)) { + RegisterCallback(env_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, + [](jobject result, FutureCallbackData *d, + bool success, void *void_data) { if (success) { UpdateCurrentUser(d->auth_data); } }); - env->DeleteLocalRef(pending_result); + env_->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -UserMetadata User::metadata() const { - if (!ValidUser(auth_data_)) return UserMetadata(); +Future UserInternal::DeleteLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_Delete)); +} - JNIEnv* env = Env(auth_data_); +UserMetadata UserInternal::metadata() const { + UserMetadata user_metadata; + if (!is_valid()) return user_metadata; - jobject userMetadata = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kGetMetadata)); - util::CheckAndClearJniExceptions(env); + jobject jUserMetadata = + env_->CallObjectMethod(user_, user::GetMethodId(user::kGetMetadata)); + util::CheckAndClearJniExceptions(env_); - if (!userMetadata) return UserMetadata(); + if (!jUserMetadata) return user_metadata; - UserMetadata data; - data.last_sign_in_timestamp = env->CallLongMethod( - userMetadata, metadata::GetMethodId(metadata::kGetLastSignInTimestamp)); - assert(env->ExceptionCheck() == false); - data.creation_timestamp = env->CallLongMethod( - userMetadata, metadata::GetMethodId(metadata::kGetCreationTimestamp)); - assert(env->ExceptionCheck() == false); + user_metadata.last_sign_in_timestamp = env_->CallLongMethod( + jUserMetadata, metadata::GetMethodId(metadata::kGetLastSignInTimestamp)); + assert(env_->ExceptionCheck() == false); + user_metadata.creation_timestamp = env_->CallLongMethod( + jUserMetadata, metadata::GetMethodId(metadata::kGetCreationTimestamp)); + assert(env_->ExceptionCheck() == false); - env->DeleteLocalRef(userMetadata); + env_->DeleteLocalRef(jUserMetadata); - return data; + return user_metadata; } -bool User::is_email_verified() const { - if (!ValidUser(auth_data_)) return false; +bool UserInternal::is_email_verified() const { + if (!is_valid()) return false; - JNIEnv* env = Env(auth_data_); - bool result = env->CallBooleanMethod( - UserImpl(auth_data_), userinfo::GetMethodId(userinfo::kIsEmailVerified)); - util::CheckAndClearJniExceptions(env); + bool result = env_->CallBooleanMethod( + user_, userinfo::GetMethodId(userinfo::kIsEmailVerified)); + util::CheckAndClearJniExceptions(env_); return result; } -bool User::is_anonymous() const { - if (!ValidUser(auth_data_)) return false; +bool UserInternal::is_anonymous() const { + if (!is_valid()) return false; - JNIEnv* env = Env(auth_data_); - bool result = env->CallBooleanMethod(UserImpl(auth_data_), - user::GetMethodId(user::kIsAnonymous)); - util::CheckAndClearJniExceptions(env); + bool result = + env_->CallBooleanMethod(user_, user::GetMethodId(user::kIsAnonymous)); + util::CheckAndClearJniExceptions(env_); return result; } +#if 0 +std::string GetUserProperty(userinfo::Method method_id, + PropertyType type = kPropertyTypeString) { + jobject property = user_info_ + ? env_->CallObjectMethod( + user_info_, userinfo::GetMethodId(method_id)) + : nullptr; + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { + return std::string(); + } + if (type == kPropertyTypeUri) { + return JniUriToString(env_, property); + } else { + // type == kPropertyTypeString + return JniStringToString(env_, property); + } + } +} +#endif + +std::string UserInternal::uid() const { + if (!is_valid()) return ""; + jobject property = + env_->CallObjectMethod(user_, userinfo::GetMethodId(userinfo::kGetUid)); + if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + return std::string(); + } + return JniStringToString(env_, property); +} + +std::string UserInternal::email() const { + if (!is_valid()) return ""; + jobject property = + env_->CallObjectMethod(user_, userinfo::GetMethodId(userinfo::kGetEmail)); + if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + return std::string(); + } + return JniStringToString(env_, property); +} + +std::string UserInternal::display_name() const { + if (!is_valid()) return ""; + jobject property = env_->CallObjectMethod( + user_, userinfo::GetMethodId(userinfo::kGetDisplayName)); + if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + return std::string(); + } + return JniStringToString(env_, property); +} + +std::string UserInternal::photo_url() const { + if (!is_valid()) return ""; + jobject property = env_->CallObjectMethod( + user_, userinfo::GetMethodId(userinfo::kGetPhotoUrl)); + if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + return std::string(); + } + return JniUriToString(env_, property); +} + +std::string UserInternal::provider_id() const { + if (!is_valid()) return ""; + jobject property = env_->CallObjectMethod( + user_, userinfo::GetMethodId(userinfo::kGetProviderId)); + if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + return std::string(); + } + return JniStringToString(env_, property); +} + +std::string UserInternal::phone_number() const { + if (!is_valid()) return ""; + jobject property = env_->CallObjectMethod( + user_, userinfo::GetMethodId(userinfo::kGetPhoneNumber)); + if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + return std::string(); + } + return JniStringToString(env_, property); +} + } // namespace auth } // namespace firebase diff --git a/auth/src/common.cc b/auth/src/common.cc index 510d1f82c0..e76e331457 100644 --- a/auth/src/common.cc +++ b/auth/src/common.cc @@ -25,6 +25,10 @@ const char* kUserNotInitializedErrorMessage = "Operation attmpted on an invalid User object."; const char* kPhoneAuthNotSupportedErrorMessage = "Phone Auth is not supported on this platform."; +const char* kAuthInvalidParameterErrorMessage = + "A parameter pass to the auth method is null or invalid."; +extern const char* kInvalidCredentialErrorMessage = + "The provided credential does not match the required type."; // static member variables const uint32_t PhoneAuthProvider::kMaxTimeoutMs = 3000; diff --git a/auth/src/common.h b/auth/src/common.h index 80674ab2bd..19038dcc4e 100644 --- a/auth/src/common.h +++ b/auth/src/common.h @@ -28,6 +28,8 @@ namespace auth { // the AdErrorCode enumeration in the C++ API. extern const char* kUserNotInitializedErrorMessage; extern const char* kPhoneAuthNotSupportedErrorMessage; +extern const char* kAuthInvalidParameterErrorMessage; +extern const char* kInvalidCredentialErrorMessage; // Enumeration for Credential API functions that return a Future. // This allows us to hold a Future for the most recent call to that API. @@ -46,12 +48,6 @@ struct FutureData { ReferenceCountedFutureImpl future_impl; }; -template -struct FutureCallbackData { - FutureData* future_data; - SafeFutureHandle future_handle; -}; - // Create a future and update the corresponding last result. template SafeFutureHandle CreateFuture(int fn_idx, FutureData* future_data) { diff --git a/auth/src/include/firebase/auth/types.h b/auth/src/include/firebase/auth/types.h index 1627e37f8a..4c0fe9c0be 100644 --- a/auth/src/include/firebase/auth/types.h +++ b/auth/src/include/firebase/auth/types.h @@ -429,8 +429,11 @@ enum AuthError { #endif // INTERNAL_EXEPERIMENTAL - /// An operation was attempted on an invalid User. + /// Indicates that an operation was attempted on an invalid User. kAuthErrorInvalidUser, + + /// Indicates that an invalid parameter was passed to an auth method. + kAuthErrorInvalidParameter, }; /// @brief Contains information required to authenticate with a third party diff --git a/auth/src/include/firebase/auth/user.h b/auth/src/include/firebase/auth/user.h index 719446266b..5278c7d593 100644 --- a/auth/src/include/firebase/auth/user.h +++ b/auth/src/include/firebase/auth/user.h @@ -386,7 +386,7 @@ class User : public UserInfoInterface { /// platforms. On other platforms this method will return a Future with a /// preset error code: kAuthErrorUnimplemented. FIREBASE_DEPRECATED Future LinkWithProvider_DEPRECATED( - FederatedAuthProvider* provider) const; + FederatedAuthProvider* provider); /// @deprecated This is a deprecated method. Please use @ref Unlink(const /// char*) instead. @@ -523,11 +523,6 @@ class User : public UserInfoInterface { virtual std::string phone_number() const; private: - // @deprecated User references to auth_data should only be needed during - // the Google I/O 23 breaking changes deprecation window. - // - // Internal only. - // // Constructor of an internal opaque type. Memory ownership of UserInternal // passes to to this User object. User(AuthData* auth_data, UserInternal* user_internal); diff --git a/auth/src/ios/common_ios.h b/auth/src/ios/common_ios.h index f5d8809752..71ccaf304e 100644 --- a/auth/src/ios/common_ios.h +++ b/auth/src/ios/common_ios.h @@ -54,6 +54,14 @@ struct AuthDataIos { FIRCPPAuthListenerHandlePointer listener_handle; }; +// Struct to contain the data required to complete +// futures asynchronously on iOS. +template +struct FutureCallbackData { + FutureData *future_data; + SafeFutureHandle future_handle; +}; + // Contains the interface between the public API and the underlying // Obj-C SDK FirebaseUser implemention. class UserInternal { @@ -160,6 +168,8 @@ class UserInternal { Mutex user_mutex_; }; +/// @deprecated +/// /// Replace the platform-dependent FIRUser object. /// Note: this function is only used to support DEPRECATED methods which return User*. This /// functionality should be removed when those deprecated methods are removed. diff --git a/auth/src/ios/credential_ios.mm b/auth/src/ios/credential_ios.mm index 8a6daaaba7..4452574cac 100644 --- a/auth/src/ios/credential_ios.mm +++ b/auth/src/ios/credential_ios.mm @@ -522,7 +522,7 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl assert(auth_data); assert(user_internal); auto handle = user_internal->future_data_.future_impl.SafeAlloc( - kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + kUserFn_ReauthenticateWithProvider_DEPRECATED, SignInResult()); #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) diff --git a/auth/src/ios/user_ios.mm b/auth/src/ios/user_ios.mm index 80d48c20c4..98d58fd757 100644 --- a/auth/src/ios/user_ios.mm +++ b/auth/src/ios/user_ios.mm @@ -171,7 +171,7 @@ return user_internal_->LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED(); } -Future User::LinkWithProvider_DEPRECATED(FederatedAuthProvider *provider) const { +Future User::LinkWithProvider_DEPRECATED(FederatedAuthProvider *provider) { assert(user_internal_); return user_internal_->LinkWithProvider_DEPRECATED(auth_data_, provider); } @@ -516,9 +516,7 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { Future UserInternal::LinkAndRetrieveDataWithCredential_DEPRECATED( AuthData *auth_data, const Credential &credential) { - // MutexLock user_info_lock(user_mutex_); if (!is_valid()) { - printf("DEDB LinkAndRetrieveDataWithCredential_DEPRECATED user is not valid\n"); SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED); Future future = MakeFuture(&future_data_.future_impl, future_handle); @@ -550,7 +548,19 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { Future UserInternal::LinkWithProvider_DEPRECATED(AuthData *auth_data, FederatedAuthProvider *provider) { - FIREBASE_ASSERT_RETURN(Future(), provider); + if (!is_valid() || provider == nullptr) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } else { + CompleteFuture(kAuthErrorInvalidParameter, kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } + return future; + } return provider->Link(auth_data, this); } @@ -610,7 +620,7 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { delete callback_data; }]; } else { - CompleteFuture(kAuthErrorInvalidCredential, kInvalidCredentialMessage, + CompleteFuture(kAuthErrorInvalidCredential, kInvalidCredentialErrorMessage, callback_data->future_handle, &future_data_, (User *)nullptr); } return future; @@ -711,7 +721,19 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { Future UserInternal::ReauthenticateWithProvider_DEPRECATED( AuthData *auth_data, FederatedAuthProvider *provider) { - FIREBASE_ASSERT_RETURN(Future(), provider); + if (!is_valid() || provider == nullptr) { + SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( + kUserFn_ReauthenticateWithProvider_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } else { + CompleteFuture(kAuthErrorInvalidParameter, kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } + return future; + } return provider->Reauthenticate(auth_data, this); } From 166f0a770503a4ccce04f2fac2b3736ed671f5dd Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Fri, 24 Mar 2023 17:56:39 -0400 Subject: [PATCH 09/14] Android builds and runs --- auth/src/android/auth_android.cc | 91 ++--- auth/src/android/common_android.cc | 18 +- auth/src/android/common_android.h | 77 ++--- auth/src/android/credential_android.cc | 38 +-- auth/src/android/user_android.cc | 438 ++++++++++++------------- auth/src/common.h | 3 - auth/src/data.h | 3 + auth/src/ios/common_ios.h | 3 + auth/src/ios/user_ios.mm | 4 +- 9 files changed, 337 insertions(+), 338 deletions(-) diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index 21506fe294..3b90161cfc 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -163,18 +163,19 @@ void ReleaseAuthClasses(JNIEnv* env) { } // Grab the user value from the Android SDK and remember it locally. -void UpdateCurrentUser(AuthData* auth_data) { +void UpdateCurrentUser(JNIEnv* env, AuthData* auth_data) { MutexLock lock(auth_data->future_impl.mutex()); - JNIEnv* env = Env(auth_data); - // Update our pointer to the Android FirebaseUser that we're wrapping. jobject j_user = env->CallObjectMethod( AuthImpl(auth_data), auth::GetMethodId(auth::kGetCurrentUser)); if (firebase::util::CheckAndClearJniExceptions(env)) { j_user = nullptr; } - - SetUserImpl(auth_data, j_user); + SetImplFromLocalRef(env, j_user, + &auth_data->deprecated_fields.android_user_impl); + SetUserImpl( + env, auth_data, + static_cast(auth_data->deprecated_fields.android_user_impl)); } // Release cached Java classes. @@ -229,6 +230,15 @@ void* CreatePlatformAuth(App* app) { void Auth::InitPlatformAuth(AuthData* auth_data) { JNIEnv* env = Env(auth_data); + // Create persistent User data to continue to facilitate deprecated aysnc + // methods which return a pointer to a User. Remove this structure when those + // deprecated methods are removed. + auth_data->deprecated_fields.android_user_impl = (jobject) nullptr; + auth_data->deprecated_fields.user_internal_deprecated = + new UserInternal(auth_data, (jobject) nullptr); + auth_data->deprecated_fields.user_deprecated = new User( + auth_data, auth_data->deprecated_fields.user_internal_deprecated); + // Create the JniAuthStateListener class to redirect the state-change // from Java to C++. jobject j_listener = @@ -260,7 +270,7 @@ void Auth::InitPlatformAuth(AuthData* auth_data) { // Ensure our User is in-line with underlying API's user. // It's possible for a user to already be logged-in on start-up. - UpdateCurrentUser(auth_data); + UpdateCurrentUser(env, auth_data); } void Auth::DestroyPlatformAuth(AuthData* auth_data) { @@ -288,7 +298,9 @@ void Auth::DestroyPlatformAuth(AuthData* auth_data) { // Clear the retained User object, which is used to support those deprecated // Auth methods which return User pointer. - SetUserImpl(auth_data, nullptr); + SetImplFromLocalRef(env, nullptr, + &auth_data->deprecated_fields.android_user_impl); + SetUserImpl(env, auth_data, nullptr); auth_data->deprecated_fields.user_internal_deprecated = nullptr; @@ -326,7 +338,7 @@ JNIEXPORT void JNICALL JniAuthStateListener_nativeOnAuthStateChanged( JNIEnv* env, jobject clazz, jlong callback_data) { AuthData* auth_data = reinterpret_cast(callback_data); // Update our pointer to the Android FirebaseUser that we're wrapping. - UpdateCurrentUser(auth_data); + UpdateCurrentUser(env, auth_data); NotifyAuthStateListeners(auth_data); } @@ -335,7 +347,7 @@ JNIEXPORT void JNICALL JniIdTokenListener_nativeOnIdTokenChanged( AuthData* auth_data = reinterpret_cast(callback_data); auth_data->SetExpectIdTokenListenerCallback(false); // Update our pointer to the Android FirebaseUser that we're wrapping. - UpdateCurrentUser(auth_data); + UpdateCurrentUser(env, auth_data); NotifyIdTokenListeners(auth_data); } @@ -344,7 +356,7 @@ static void ReadProviderResult( jobject result, FutureCallbackData* d, bool success, void* void_data) { auto data = static_cast(void_data); - JNIEnv* env = d->env; + JNIEnv* env = Env(d->auth_data); // `result` comes from the successfully completed Task in Java. If the Task // completed successfully, `result` should be valid. @@ -389,8 +401,8 @@ Future Auth::FetchProvidersForEmail( env->DeleteLocalRef(j_email); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(env, pending_result, handle, auth_data_->future_api_id, - &futures, ReadProviderResult); + RegisterCallback(auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, ReadProviderResult); env->DeleteLocalRef(pending_result); } return MakeFuture(&futures, handle); @@ -411,10 +423,9 @@ Future Auth::SignInWithCustomToken_DEPRECATED(const char* token) { env->DeleteLocalRef(j_token); if (!CheckAndCompleteFutureOnError(env, &futures, future_handle)) { - RegisterCallbackWithAuthData(env, auth_data_, pending_result, future_handle, - auth_data_->future_api_id, - &auth_data_->future_impl, - ReadUserFromSignInResult); + RegisterCallback(auth_data_, pending_result, future_handle, + auth_data_->future_api_id, &auth_data_->future_impl, + ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } return future; @@ -437,9 +448,9 @@ Future Auth::SignInWithCredential_DEPRECATED( CredentialFromImpl(credential.impl_)); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallbackWithAuthData(env, auth_data_, pending_result, handle, - auth_data_->future_api_id, &futures, - ReadUserFromSignInResult); + RegisterCallback(auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, + ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } } @@ -463,9 +474,9 @@ Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( if (!CheckAndCompleteFutureOnError(env, &auth_data_->future_impl, future_handle)) { - RegisterCallbackWithAuthData(env, auth_data_, pending_result, - future_handle, auth_data_->future_api_id, - &auth_data_->future_impl, ReadSignInResult); + RegisterCallback(auth_data_, pending_result, future_handle, + auth_data_->future_api_id, &auth_data_->future_impl, + ReadSignInResult); env->DeleteLocalRef(pending_result); } } @@ -479,22 +490,21 @@ Future Auth::SignInWithProvider_DEPRECATED( } Future Auth::SignInAnonymously_DEPRECATED() { - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED); + const auto handle = auth_data_->future_impl.SafeAlloc( + kAuthFn_SignInAnonymously_DEPRECATED); JNIEnv* env = Env(auth_data_); jobject pending_result = env->CallObjectMethod( AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInAnonymously)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallbackWithAuthData(env, auth_data_, pending_result, handle, - auth_data_->future_api_id, &futures, - ReadUserFromSignInResult); + if (!CheckAndCompleteFutureOnError(env, &auth_data_->future_impl, handle)) { + RegisterCallback(auth_data_, pending_result, handle, + auth_data_->future_api_id, &auth_data_->future_impl, + ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return MakeFuture(&auth_data_->future_impl, handle); } Future Auth::SignInWithEmailAndPassword_DEPRECATED( @@ -522,9 +532,9 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED( env->DeleteLocalRef(j_password); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallbackWithAuthData(env, auth_data_, pending_result, handle, - auth_data_->future_api_id, &futures, - ReadUserFromSignInResult); + RegisterCallback(auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, + ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } @@ -557,10 +567,9 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( if (!CheckAndCompleteFutureOnError(env, &auth_data_->future_impl, future_handle)) { - RegisterCallbackWithAuthData(env, auth_data_, pending_result, future_handle, - auth_data_->future_api_id, - &auth_data_->future_impl, - ReadUserFromSignInResult); + RegisterCallback(auth_data_, pending_result, future_handle, + auth_data_->future_api_id, &auth_data_->future_impl, + ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } return MakeFuture(&auth_data_->future_impl, future_handle); @@ -624,7 +633,9 @@ void Auth::SignOut() { // Release our current user implementation in Java. MutexLock lock(auth_data_->future_impl.mutex()); - SetUserImpl(auth_data_, nullptr); + SetImplFromLocalRef(env, nullptr, + &auth_data_->deprecated_fields.android_user_impl); + SetUserImpl(env, auth_data_, nullptr); } Future Auth::SendPasswordResetEmail(const char* email) { @@ -643,8 +654,8 @@ Future Auth::SendPasswordResetEmail(const char* email) { env->DeleteLocalRef(j_email); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(env, pending_result, handle, auth_data_->future_api_id, - &futures, nullptr); + RegisterCallback(auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, nullptr); env->DeleteLocalRef(pending_result); } return MakeFuture(&futures, handle); diff --git a/auth/src/android/common_android.cc b/auth/src/android/common_android.cc index 0cfd44d594..f0dea43cf8 100644 --- a/auth/src/android/common_android.cc +++ b/auth/src/android/common_android.cc @@ -472,7 +472,7 @@ void SetImplFromLocalRef(JNIEnv* env, jobject j_local, void** impl) { // Reads the `AuthResult` in `result` and initialize the `User*` in `void_data`. void ReadSignInResult(jobject result, FutureCallbackData* d, bool success, void* void_data) { - JNIEnv* env = d->env; + JNIEnv* env = Env(d->auth_data); // Update the currently signed-in user on success. // Note: `result` is only valid when success is true. @@ -483,9 +483,13 @@ void ReadSignInResult(jobject result, FutureCallbackData* d, util::CheckAndClearJniExceptions(env); // Update our pointer to the Android FirebaseUser that we're wrapping. - // Note: Cannot call UpdateCurrentUser(d->auth_data) because the Java + // Note: Cannot call UpdateCurrentUser(env, d->auth_data) because the Java // Auth class has not been updated at this point. - SetUserImpl(d->auth_data, j_user); + SetImplFromLocalRef(env, j_user, + &d->auth_data->deprecated_fields.android_user_impl); + SetUserImpl(env, d->auth_data, + static_cast( + d->auth_data->deprecated_fields.android_user_impl)); // Grab the additional user info too. // Additional user info is not guaranteed to exist, so could be nullptr. @@ -519,9 +523,13 @@ void ReadUserFromSignInResult(jobject result, FutureCallbackData* d, util::CheckAndClearJniExceptions(env); // Update our pointer to the Android FirebaseUser that we're wrapping. - // Note: Cannot call UpdateCurrentUser(d->auth_data) because the Java + // Note: Cannot call UpdateCurrentUser(env, d->auth_data) because the Java // Auth class has not been updated at this point. - SetUserImpl(d->auth_data, j_user); + SetImplFromLocalRef(env, j_user, + &d->auth_data->deprecated_fields.android_user_impl); + SetUserImpl(env, d->auth_data, + static_cast( + d->auth_data->deprecated_fields.android_user_impl)); } // Return a pointer to the current user, if the current user is valid. diff --git a/auth/src/android/common_android.h b/auth/src/android/common_android.h index 6382b338a8..cb8a9a2dc3 100644 --- a/auth/src/android/common_android.h +++ b/auth/src/android/common_android.h @@ -54,17 +54,13 @@ struct FutureCallbackData { FutureCallbackData* future_callback_Data, bool success, void* void_data); - FutureCallbackData(JNIEnv* env, AuthData* auth_data, - const SafeFutureHandle& handle, + FutureCallbackData(AuthData* auth_data, const SafeFutureHandle& handle, ReferenceCountedFutureImpl* future_impl, ReadFutureResultFn* future_data_read_fn) - : env(env), - auth_data(auth_data), + : auth_data(auth_data), handle(handle), future_impl(future_impl), future_data_read_fn(future_data_read_fn) {} - - JNIEnv* env; AuthData* auth_data; SafeFutureHandle handle; ReferenceCountedFutureImpl* future_impl; @@ -76,7 +72,7 @@ struct FutureCallbackData { class UserInternal { public: // Constructor - explicit UserInternal(JNIEnv* env, jobject android_user); + explicit UserInternal(AuthData* auth_data, jobject android_user); // Copy constructor. UserInternal(const UserInternal& user_internal); @@ -86,12 +82,14 @@ class UserInternal { // @deprecated // // Provides a mechanism for the deprecated auth-contained user object to - // update its underlying Android Java SDK FirebaseUser object. + // update its underlying Android Java SDK FirebaseUser object. Assumes that + // a global ref has already been set on android_user. Releases the global + // ref on any previously held user. void set_native_user_object_deprecated(jobject android_user); bool is_valid() const; - Future GetToken(AuthData* auth_data, bool force_refresh); + Future GetToken(bool force_refresh); Future GetTokenLastResult() const; Future UpdateEmail(const char* email); @@ -109,24 +107,23 @@ class UserInternal { Future SendEmailVerification(); Future SendEmailVerificationLastResult() const; - Future LinkWithCredential_DEPRECATED(AuthData* auth_data, - const Credential& credential); + Future LinkWithCredential_DEPRECATED(const Credential& credential); Future LinkWithCredentialLastResult_DEPRECATED() const; Future LinkAndRetrieveDataWithCredential_DEPRECATED( - AuthData* auth_data_, const Credential& credential); + const Credential& credential); Future LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const; Future LinkWithProvider_DEPRECATED( - AuthData* auth_data, FederatedAuthProvider* provider); + FederatedAuthProvider* provider); Future LinkWithProviderLastResult_DEPRECATED() const; - Future Unlink_DEPRECATED(AuthData* auth_data, const char* provider); + Future Unlink_DEPRECATED(const char* provider); Future UnlinkLastResult_DEPRECATED() const; Future UpdatePhoneNumberCredential_DEPRECATED( - AuthData* auth_data, const Credential& credential); + const Credential& credential); Future UpdatePhoneNumberCredentialLastResult_DEPRECATED() const; Future Reload(); @@ -136,15 +133,15 @@ class UserInternal { Future ReauthenticateLastResult() const; Future ReauthenticateAndRetrieveData_DEPRECATED( - AuthData* auth_data, const Credential& credential); + const Credential& credential); Future ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const; Future ReauthenticateWithProvider_DEPRECATED( - AuthData* auth_data, FederatedAuthProvider* provider); + FederatedAuthProvider* provider); Future ReauthenticateWithProviderLastResult_DEPRECATED() const; - Future Delete(AuthData* auth_data); + Future Delete(); Future DeleteLastResult() const; UserMetadata metadata() const; @@ -163,12 +160,12 @@ class UserInternal { void clear_user_infos(); + // Pointer to the originating auth context. + AuthData* auth_data_; + // Android Java SDK Implementation of a FirebaseUser object. jobject user_; - // Pointer to the app's JNI environment context. - JNIEnv* env_; - // Future data used to synchronize asynchronous calls. FutureData future_data_; @@ -235,13 +232,18 @@ inline JNIEnv* Env(AuthData* auth_data) { return auth_data->app->GetJNIEnv(); } // Delete the existing impl pointer global reference, if it already exists. void SetImplFromLocalRef(JNIEnv* env, jobject j_local, void** impl); +// Synchronize the current user. +void UpdateCurrentUser(JNIEnv* env, AuthData* auth_data); + /// @deprecated /// /// Replace the platform-dependent FirebaseUser Android SDK object. /// Note: this function is only used to support DEPRECATED methods which return /// User*. This functionality should be removed when those deprecated methods /// are removed. -inline void SetUserImpl(AuthData* _Nonnull auth_data, jobject j_user) { +inline void SetUserImpl(JNIEnv* env, AuthData* _Nonnull auth_data, + jobject j_user) { + assert(auth_data->deprecated_fields.user_internal_deprecated); auth_data->deprecated_fields.user_internal_deprecated ->set_native_user_object_deprecated(j_user); } @@ -364,28 +366,13 @@ void FederatedAuthProviderFutureCallback(JNIEnv* env, jobject result, // data from Java, and then complete the Future for `handle`. template void RegisterCallback( - JNIEnv* env, jobject pending_result, SafeFutureHandle handle, + AuthData* auth_data, jobject pending_result, SafeFutureHandle handle, const std::string& future_api_id, ReferenceCountedFutureImpl* future_impl, typename FutureCallbackData::ReadFutureResultFn read_result_fn) { // The FutureCallbackData structure is deleted in FutureCallback(). util::RegisterCallbackOnTask( - env, pending_result, FutureCallback, - new FutureCallbackData(env, /*auth_data=*/nullptr, handle, future_impl, - read_result_fn), - future_api_id.c_str()); -} - -template -void RegisterCallbackWithAuthData( - JNIEnv* env, AuthData* auth_data, jobject pending_result, - SafeFutureHandle handle, const std::string& future_api_id, - ReferenceCountedFutureImpl* future_impl, - typename FutureCallbackData::ReadFutureResultFn read_result_fn) { - // The FutureCallbackData structure is deleted in FutureCallback(). - util::RegisterCallbackOnTask( - env, pending_result, FutureCallback, - new FutureCallbackData(env, auth_data, handle, future_impl, - read_result_fn), + Env(auth_data), pending_result, FutureCallback, + new FutureCallbackData(auth_data, handle, future_impl, read_result_fn), future_api_id.c_str()); } @@ -396,16 +383,14 @@ void RegisterCallbackWithAuthData( // with the existing API behavior for other sign in events. template void RegisterFederatedAuthProviderCallback( - JNIEnv* env, AuthData* auth_data, jobject pending_result, - SafeFutureHandle handle, const std::string& future_api_id, - ReferenceCountedFutureImpl* future_impl, + AuthData* auth_data, jobject pending_result, SafeFutureHandle handle, + const std::string& future_api_id, ReferenceCountedFutureImpl* future_impl, typename FutureCallbackData::ReadFutureResultFn read_result_fn) { // The FutureCallbackData structure is deleted in // FederatedAuthProviderFutureCallback(). util::RegisterCallbackOnTask( - env, pending_result, FederatedAuthProviderFutureCallback, - new FutureCallbackData(env, auth_data, handle, future_impl, - read_result_fn), + Env(auth_data), pending_result, FederatedAuthProviderFutureCallback, + new FutureCallbackData(auth_data, handle, future_impl, read_result_fn), future_api_id.c_str()); } diff --git a/auth/src/android/credential_android.cc b/auth/src/android/credential_android.cc index 5b84e3ddcf..1c06f266b7 100644 --- a/auth/src/android/credential_android.cc +++ b/auth/src/android/credential_android.cc @@ -1026,8 +1026,8 @@ Future FederatedOAuthProvider::SignIn(AuthData* auth_data) { if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { RegisterFederatedAuthProviderCallback( - Env(auth_data), auth_data, task, future_handle, - auth_data->future_api_id, &auth_data->future_impl, ReadSignInResult); + auth_data, task, future_handle, auth_data->future_api_id, + &auth_data->future_impl, ReadSignInResult); } env->DeleteLocalRef(task); } @@ -1043,23 +1043,22 @@ Future FederatedOAuthProvider::Link(AuthData* auth_data, const auto future_handle = future_impl.SafeAlloc( kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + JNIEnv* env = Env(auth_data); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); - if (!CheckAndCompleteFutureOnError(user_internal->env_, &future_impl, - future_handle)) { - jobject task = user_internal->env_->CallObjectMethod( + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { + jobject task = env->CallObjectMethod( user_internal->user_, user_idp::GetMethodId(user_idp::kStartActivityForLinkWithProvider), auth_data->app->activity(), oauthprovider); - if (!CheckAndCompleteFutureOnError(user_internal->env_, &future_impl, - future_handle)) { + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { RegisterFederatedAuthProviderCallback( - Env(auth_data), auth_data, task, future_handle, - auth_data->future_api_id, &auth_data->future_impl, ReadSignInResult); + auth_data, task, future_handle, auth_data->future_api_id, + &auth_data->future_impl, ReadSignInResult); } - Env(auth_data)->DeleteLocalRef(task); + env->DeleteLocalRef(task); } - user_internal->env_->DeleteLocalRef(oauthprovider); + env->DeleteLocalRef(oauthprovider); return MakeFuture(&future_impl, future_handle); } @@ -1070,24 +1069,23 @@ Future FederatedOAuthProvider::Reauthenticate( const auto future_handle = future_impl.SafeAlloc( kUserFn_ReauthenticateWithProvider_DEPRECATED, SignInResult()); + JNIEnv* env = Env(auth_data); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); - if (!CheckAndCompleteFutureOnError(user_internal->env_, &future_impl, - future_handle)) { - jobject task = user_internal->env_->CallObjectMethod( + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { + jobject task = env->CallObjectMethod( user_internal->user_, user_idp::GetMethodId( user_idp::kStartActivityForReauthenticateWithProvider), auth_data->app->activity(), oauthprovider); - if (!CheckAndCompleteFutureOnError(user_internal->env_, &future_impl, - future_handle)) { + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { RegisterFederatedAuthProviderCallback( - Env(auth_data), auth_data, task, future_handle, - auth_data->future_api_id, &auth_data->future_impl, ReadSignInResult); + auth_data, task, future_handle, auth_data->future_api_id, + &auth_data->future_impl, ReadSignInResult); } - user_internal->env_->DeleteLocalRef(task); + env->DeleteLocalRef(task); } - user_internal->env_->DeleteLocalRef(oauthprovider); + env->DeleteLocalRef(oauthprovider); return MakeFuture(&future_impl, future_handle); } diff --git a/auth/src/android/user_android.cc b/auth/src/android/user_android.cc index 55212748ef..69d81d0de9 100644 --- a/auth/src/android/user_android.cc +++ b/auth/src/android/user_android.cc @@ -154,18 +154,20 @@ enum PropertyType { kPropertyTypeString, kPropertyTypeUri }; class AndroidWrappedUserInfo : public UserInfoInterface { public: - AndroidWrappedUserInfo(JNIEnv *env, jobject user_info) - : env_(env), user_info_(user_info) { + AndroidWrappedUserInfo(AuthData *auth_data, jobject user_info) + : auth_data_(auth_data), user_info_(user_info) { // Convert `user_info` to a global reference. - user_info_ = env_->NewGlobalRef(user_info); + JNIEnv *env = Env(auth_data_); + user_info_ = env->NewGlobalRef(user_info); env->DeleteLocalRef(user_info); } virtual ~AndroidWrappedUserInfo() { // Delete global reference. - env_->DeleteGlobalRef(user_info_); + JNIEnv *env = Env(auth_data_); + env->DeleteGlobalRef(user_info_); user_info_ = nullptr; - env_ = nullptr; + auth_data_ = nullptr; } std::string uid() const override { @@ -195,23 +197,24 @@ class AndroidWrappedUserInfo : public UserInfoInterface { private: std::string GetUserProperty(userinfo::Method method_id, PropertyType type = kPropertyTypeString) const { + JNIEnv *env = Env(auth_data_); jobject property = user_info_ - ? env_->CallObjectMethod( + ? env->CallObjectMethod( user_info_, userinfo::GetMethodId(method_id)) : nullptr; - if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { return std::string(); } if (type == kPropertyTypeUri) { - return JniUriToString(env_, property); + return JniUriToString(env, property); } else { // type == kPropertyTypeString - return JniStringToString(env_, property); + return JniStringToString(env, property); } } - /// The app's JNIEnv context. Required to invoke Java API methods. - JNIEnv *env_; + /// The AuthData context, required JNI environment data. + AuthData *auth_data_; /// Pointer to the main class. /// Needed for context in implementation of virtuals. @@ -224,14 +227,14 @@ class AndroidWrappedUserInfo : public UserInfoInterface { /// User::User(AuthData *auth_data, UserInternal *user_internal) { assert(auth_data); + auth_data_ = auth_data; if (user_internal == nullptr) { // Create an invalid user internal. // This will return is_valid() false, and operations will fail. - user_internal_ = new UserInternal(Env(auth_data), nullptr); + user_internal_ = new UserInternal(auth_data_, nullptr); } else { user_internal_ = user_internal; } - auth_data_ = auth_data; } User::~User() { @@ -243,13 +246,15 @@ User::~User() { User &User::operator=(const User &user) { assert(user_internal_); delete user_internal_; + + auth_data_ = user.auth_data_; + if (user.user_internal_ != nullptr) { - user_internal_ = - new UserInternal(user.user_internal_->env_, user.user_internal_->user_); + user_internal_ = new UserInternal(auth_data_, user.user_internal_->user_); } else { - user_internal_ = new UserInternal(Env(user.auth_data_), nullptr); + user_internal_ = new UserInternal(user.auth_data_, nullptr); } - auth_data_ = user.auth_data_; + return *this; } @@ -260,7 +265,7 @@ bool User::is_valid() const { Future User::GetToken(bool force_refresh) { assert(user_internal_); - return user_internal_->GetToken(auth_data_, force_refresh); + return user_internal_->GetToken(force_refresh); } std::vector User::provider_data() const { @@ -306,8 +311,7 @@ Future User::ReauthenticateLastResult() const { Future User::ReauthenticateAndRetrieveData_DEPRECATED( const Credential &credential) { assert(user_internal_); - return user_internal_->ReauthenticateAndRetrieveData_DEPRECATED(auth_data_, - credential); + return user_internal_->ReauthenticateAndRetrieveData_DEPRECATED(credential); } Future User::ReauthenticateAndRetrieveDataLastResult_DEPRECATED() @@ -319,8 +323,7 @@ Future User::ReauthenticateAndRetrieveDataLastResult_DEPRECATED() Future User::ReauthenticateWithProvider_DEPRECATED( FederatedAuthProvider *provider) const { assert(user_internal_); - return user_internal_->ReauthenticateWithProvider_DEPRECATED(auth_data_, - provider); + return user_internal_->ReauthenticateWithProvider_DEPRECATED(provider); } Future User::SendEmailVerification() { @@ -346,7 +349,7 @@ Future User::UpdateUserProfileLastResult() const { Future User::LinkWithCredential_DEPRECATED( const Credential &credential) { assert(user_internal_); - return user_internal_->LinkWithCredential_DEPRECATED(auth_data_, credential); + return user_internal_->LinkWithCredential_DEPRECATED(credential); } Future User::LinkWithCredentialLastResult_DEPRECATED() const { @@ -358,7 +361,7 @@ Future User::LinkAndRetrieveDataWithCredential_DEPRECATED( const Credential &credential) { assert(user_internal_); return user_internal_->LinkAndRetrieveDataWithCredential_DEPRECATED( - auth_data_, credential); + credential); } Future @@ -371,12 +374,12 @@ User::LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const { Future User::LinkWithProvider_DEPRECATED( FederatedAuthProvider *provider) { assert(user_internal_); - return user_internal_->LinkWithProvider_DEPRECATED(auth_data_, provider); + return user_internal_->LinkWithProvider_DEPRECATED(provider); } Future User::Unlink_DEPRECATED(const char *provider) { assert(user_internal_); - return user_internal_->Unlink_DEPRECATED(auth_data_, provider); + return user_internal_->Unlink_DEPRECATED(provider); } Future User::UnlinkLastResult_DEPRECATED() const { @@ -387,8 +390,7 @@ Future User::UnlinkLastResult_DEPRECATED() const { Future User::UpdatePhoneNumberCredential_DEPRECATED( const Credential &credential) { assert(user_internal_); - return user_internal_->UpdatePhoneNumberCredential_DEPRECATED(auth_data_, - credential); + return user_internal_->UpdatePhoneNumberCredential_DEPRECATED(credential); } Future User::UpdatePhoneNumberCredentialLastResult_DEPRECATED() const { @@ -408,7 +410,7 @@ Future User::ReloadLastResult() const { Future User::Delete() { assert(user_internal_); - return user_internal_->Delete(auth_data_); + return user_internal_->Delete(); } Future User::DeleteLastResult() const { @@ -475,23 +477,30 @@ void assign_future_id(UserInternal *user_internal, std::string *future_api_id) { reinterpret_cast(user_internal))); } -UserInternal::UserInternal(JNIEnv *env, jobject user) - : env_(env), user_(user), future_data_(kUserFnCount) { +UserInternal::UserInternal(AuthData *auth_data, jobject user) + : auth_data_(auth_data), user_(nullptr), future_data_(kUserFnCount) { + assert(auth_data_); + JNIEnv *env = Env(auth_data_); + if (user != nullptr) { + user_ = env->NewGlobalRef(user); + assert(env->ExceptionCheck() == false); + } assign_future_id(this, &future_api_id_); } UserInternal::UserInternal(const UserInternal &user_internal) - : env_(user_internal.env_), + : auth_data_(user_internal.auth_data_), user_(user_internal.user_), future_data_(kUserFnCount) { assign_future_id(this, &future_api_id_); } UserInternal::~UserInternal() { - util::CancelCallbacks(env_, future_api_id_.c_str()); + MutexLock user_lock(user_mutex_); + JNIEnv *env = Env(auth_data_); + util::CancelCallbacks(env, future_api_id_.c_str()); - env_->DeleteGlobalRef(user_); - env_ = nullptr; + env->DeleteGlobalRef(user_); user_ = nullptr; { @@ -503,17 +512,11 @@ UserInternal::~UserInternal() { while (!future_data_.future_impl.IsSafeToDelete()) { internal::Sleep(100); } + auth_data_ = nullptr; } void UserInternal::set_native_user_object_deprecated(jobject user) { - MutexLock user_info_lock(user_mutex_); - if (user_ != nullptr) { - env_->DeleteGlobalRef(user_); - } - - if (user != nullptr) { - user = env_->NewGlobalRef(user); - } + MutexLock user_lock(user_mutex_); user_ = user; } @@ -530,7 +533,7 @@ void UserInternal::clear_user_infos() { void ReadTokenResult(jobject result, FutureCallbackData *d, bool success, void *void_data) { auto data = static_cast(void_data); - JNIEnv *env = d->env; + JNIEnv *env = Env(d->auth_data); // `result` is of type GetTokenResult when `success` is true. if (success) { @@ -549,17 +552,12 @@ void ReadTokenResult(jobject result, FutureCallbackData *d, } } -Future UserInternal::GetToken(AuthData *auth_data, - bool force_refresh) { +Future UserInternal::GetToken(bool force_refresh) { MutexLock user_info_lock(user_mutex_); if (!is_valid()) { return CreateAndCompleteFuture(kUserFn_GetToken, kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, &future_data_, ""); - } else if (nullptr == auth_data) { - return CreateAndCompleteFuture(kUserFn_GetToken, kAuthErrorFailure, - "Internal AuthData nullptr", &future_data_, - ""); } SafeFutureHandle future_handle = @@ -567,46 +565,47 @@ Future UserInternal::GetToken(AuthData *auth_data, Future future = MakeFuture(&future_data_.future_impl, future_handle); - auth_data->SetExpectIdTokenListenerCallback(force_refresh); + auth_data_->SetExpectIdTokenListenerCallback(force_refresh); - jobject pending_result = env_->CallObjectMethod( + JNIEnv *env = Env(auth_data_); + jobject pending_result = env->CallObjectMethod( user_, user::GetMethodId(user::kToken), force_refresh); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallbackWithAuthData(env_, auth_data, pending_result, future_handle, - future_api_id_, &future_data_.future_impl, - ReadTokenResult); - env_->DeleteLocalRef(pending_result); + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadTokenResult); + env->DeleteLocalRef(pending_result); } else { // If the method failed for some reason, clear the expected callback. - auth_data->SetExpectIdTokenListenerCallback(false); + auth_data_->SetExpectIdTokenListenerCallback(false); } return future; } std::vector UserInternal::provider_data() const { + JNIEnv *env = Env(auth_data_); std::vector local_user_infos; if (is_valid()) { const jobject list = - env_->CallObjectMethod(user_, user::GetMethodId(user::kProviderData)); - assert(env_->ExceptionCheck() == false); + env->CallObjectMethod(user_, user::GetMethodId(user::kProviderData)); + assert(env->ExceptionCheck() == false); if (list != nullptr) { const int num_providers = - env_->CallIntMethod(list, util::list::GetMethodId(util::list::kSize)); - assert(env_->ExceptionCheck() == false); + env->CallIntMethod(list, util::list::GetMethodId(util::list::kSize)); + assert(env->ExceptionCheck() == false); local_user_infos.resize(num_providers); for (int i = 0; i < num_providers; ++i) { // user_info is converted to a global reference in // AndroidWrappedUserInfo() and the local reference is released. - jobject user_info = env_->CallObjectMethod( + jobject user_info = env->CallObjectMethod( list, util::list::GetMethodId(util::list::kGet), i); - assert(env_->ExceptionCheck() == false); - local_user_infos[i] = AndroidWrappedUserInfo(env_, user_info); + assert(env->ExceptionCheck() == false); + local_user_infos[i] = AndroidWrappedUserInfo(auth_data_, user_info); } - env_->DeleteLocalRef(list); + env->DeleteLocalRef(list); } } return local_user_infos; @@ -617,27 +616,28 @@ const std::vector MutexLock user_info_lock(user_info_mutex_deprecated_); clear_user_infos(); if (is_valid()) { + JNIEnv *env = Env(auth_data_); // getProviderData returns `List` const jobject list = - env_->CallObjectMethod(user_, user::GetMethodId(user::kProviderData)); - assert(env_->ExceptionCheck() == false); + env->CallObjectMethod(user_, user::GetMethodId(user::kProviderData)); + assert(env->ExceptionCheck() == false); // Copy the list into user_infos_. if (list != nullptr) { const int num_providers = - env_->CallIntMethod(list, util::list::GetMethodId(util::list::kSize)); - assert(env_->ExceptionCheck() == false); + env->CallIntMethod(list, util::list::GetMethodId(util::list::kSize)); + assert(env->ExceptionCheck() == false); user_infos_.resize(num_providers); for (int i = 0; i < num_providers; ++i) { // user_info is converted to a global reference in // AndroidWrappedUserInfo() and the local reference is released. - jobject user_info = env_->CallObjectMethod( + jobject user_info = env->CallObjectMethod( list, util::list::GetMethodId(util::list::kGet), i); - assert(env_->ExceptionCheck() == false); - user_infos_[i] = new AndroidWrappedUserInfo(env_, user_info); + assert(env->ExceptionCheck() == false); + user_infos_[i] = new AndroidWrappedUserInfo(auth_data_, user_info); } - env_->DeleteLocalRef(list); + env->DeleteLocalRef(list); } } // Return a reference to our internally-backed values. @@ -655,16 +655,17 @@ Future UserInternal::UpdateEmail(const char *email) { future_data_.future_impl.SafeAlloc(kUserFn_UpdateEmail); Future future = MakeFuture(&future_data_.future_impl, future_handle); - jstring j_email = env_->NewStringUTF(email); - jobject pending_result = env_->CallObjectMethod( + JNIEnv *env = Env(auth_data_); + jstring j_email = env->NewStringUTF(email); + jobject pending_result = env->CallObjectMethod( user_, user::GetMethodId(user::kUpdateEmail), j_email); - env_->DeleteLocalRef(j_email); + env->DeleteLocalRef(j_email); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallback(env_, pending_result, future_handle, future_api_id_, + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, &future_data_.future_impl, nullptr); - env_->DeleteLocalRef(pending_result); + env->DeleteLocalRef(pending_result); } return future; } @@ -685,16 +686,17 @@ Future UserInternal::UpdatePassword(const char *password) { future_data_.future_impl.SafeAlloc(kUserFn_UpdatePassword); Future future = MakeFuture(&future_data_.future_impl, future_handle); - jstring j_password = env_->NewStringUTF(password); - jobject pending_result = env_->CallObjectMethod( + JNIEnv *env = Env(auth_data_); + jstring j_password = env->NewStringUTF(password); + jobject pending_result = env->CallObjectMethod( user_, user::GetMethodId(user::kUpdatePassword), j_password); - env_->DeleteLocalRef(j_password); + env->DeleteLocalRef(j_password); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallback(env_, pending_result, future_handle, future_api_id_, + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, &future_data_.future_impl, nullptr); - env_->DeleteLocalRef(pending_result); + env->DeleteLocalRef(pending_result); } return future; } @@ -716,61 +718,62 @@ Future UserInternal::UpdateUserProfile(const User::UserProfile &profile) { future_data_.future_impl.SafeAlloc(kUserFn_UpdateUserProfile); Future future = MakeFuture(&future_data_.future_impl, future_handle); + JNIEnv *env = Env(auth_data_); AuthError error = kAuthErrorNone; std::string exception_error_message; - jobject j_user_profile_builder = env_->NewObject( + jobject j_user_profile_builder = env->NewObject( userprofilebuilder::GetClass(), userprofilebuilder::GetMethodId(userprofilebuilder::kConstructor)); // Call UserProfileChangeRequest.Builder.setDisplayName. if (profile.display_name != nullptr) { - jstring j_display_name = env_->NewStringUTF(profile.display_name); - jobject j_builder_discard = env_->CallObjectMethod( + jstring j_display_name = env->NewStringUTF(profile.display_name); + jobject j_builder_discard = env->CallObjectMethod( j_user_profile_builder, userprofilebuilder::GetMethodId(userprofilebuilder::kSetDisplayName), j_display_name); - error = CheckAndClearJniAuthExceptions(env_, &exception_error_message); + error = CheckAndClearJniAuthExceptions(env, &exception_error_message); if (j_builder_discard) { - env_->DeleteLocalRef(j_builder_discard); + env->DeleteLocalRef(j_builder_discard); } - env_->DeleteLocalRef(j_display_name); + env->DeleteLocalRef(j_display_name); } // Call UserProfileChangeRequest.Builder.setPhotoUri. if (error == kAuthErrorNone && profile.photo_url != nullptr) { - jobject j_uri = CharsToJniUri(env_, profile.photo_url); - jobject j_builder_discard = env_->CallObjectMethod( + jobject j_uri = CharsToJniUri(env, profile.photo_url); + jobject j_builder_discard = env->CallObjectMethod( j_user_profile_builder, userprofilebuilder::GetMethodId(userprofilebuilder::kSetPhotoUri), j_uri); - error = CheckAndClearJniAuthExceptions(env_, &exception_error_message); + error = CheckAndClearJniAuthExceptions(env, &exception_error_message); if (j_builder_discard) { - env_->DeleteLocalRef(j_builder_discard); + env->DeleteLocalRef(j_builder_discard); } - env_->DeleteLocalRef(j_uri); + env->DeleteLocalRef(j_uri); } jobject j_user_profile_request = nullptr; if (error == kAuthErrorNone) { // Call UserProfileChangeRequest.Builder.build. - j_user_profile_request = env_->CallObjectMethod( + j_user_profile_request = env->CallObjectMethod( j_user_profile_builder, userprofilebuilder::GetMethodId(userprofilebuilder::kBuild)); - error = CheckAndClearJniAuthExceptions(env_, &exception_error_message); + error = CheckAndClearJniAuthExceptions(env, &exception_error_message); } if (error == kAuthErrorNone) { // Call FirebaseUser.updateProfile. - jobject pending_result = env_->CallObjectMethod( + jobject pending_result = env->CallObjectMethod( user_, user::GetMethodId(user::kUpdateUserProfile), j_user_profile_request); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallback(env_, pending_result, future_handle, future_api_id_, - &future_data_.future_impl, nullptr); - env_->DeleteLocalRef(pending_result); + RegisterCallback(auth_data_, pending_result, future_handle, + future_api_id_, &future_data_.future_impl, nullptr); + env->DeleteLocalRef(pending_result); } return future; } else { @@ -778,9 +781,9 @@ Future UserInternal::UpdateUserProfile(const User::UserProfile &profile) { exception_error_message.c_str()); } if (j_user_profile_request) { - env_->DeleteLocalRef(j_user_profile_request); + env->DeleteLocalRef(j_user_profile_request); } - env_->DeleteLocalRef(j_user_profile_builder); + env->DeleteLocalRef(j_user_profile_builder); return future; } @@ -801,14 +804,15 @@ Future UserInternal::SendEmailVerification() { future_data_.future_impl.SafeAlloc(kUserFn_SendEmailVerification); Future future = MakeFuture(&future_data_.future_impl, future_handle); - jobject pending_result = env_->CallObjectMethod( + JNIEnv *env = Env(auth_data_); + jobject pending_result = env->CallObjectMethod( user_, user::GetMethodId(user::kSendEmailVerification)); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallback(env_, pending_result, future_handle, future_api_id_, + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, &future_data_.future_impl, nullptr); - env_->DeleteLocalRef(pending_result); + env->DeleteLocalRef(pending_result); } return future; } @@ -819,7 +823,7 @@ Future UserInternal::SendEmailVerificationLastResult() const { } Future UserInternal::LinkWithCredential_DEPRECATED( - AuthData *auth_data, const Credential &credential) { + const Credential &credential) { MutexLock user_info_lock(user_mutex_); SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( @@ -832,16 +836,16 @@ Future UserInternal::LinkWithCredential_DEPRECATED( return future; } - jobject pending_result = env_->CallObjectMethod( - user_, user::GetMethodId(user::kLinkWithCredential), - CredentialFromImpl(credential.impl_)); + JNIEnv *env = Env(auth_data_); + jobject pending_result = + env->CallObjectMethod(user_, user::GetMethodId(user::kLinkWithCredential), + CredentialFromImpl(credential.impl_)); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallbackWithAuthData(env_, auth_data, pending_result, future_handle, - future_api_id_, &future_data_.future_impl, - ReadUserFromSignInResult); - env_->DeleteLocalRef(pending_result); + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadUserFromSignInResult); + env->DeleteLocalRef(pending_result); } return future; } @@ -853,7 +857,7 @@ Future UserInternal::LinkWithCredentialLastResult_DEPRECATED() const { } Future UserInternal::LinkAndRetrieveDataWithCredential_DEPRECATED( - AuthData *auth_data, const Credential &credential) { + const Credential &credential) { SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED); @@ -865,16 +869,16 @@ Future UserInternal::LinkAndRetrieveDataWithCredential_DEPRECATED( return future; } - jobject pending_result = env_->CallObjectMethod( - user_, user::GetMethodId(user::kLinkWithCredential), - CredentialFromImpl(credential.impl_)); + JNIEnv *env = Env(auth_data_); + jobject pending_result = + env->CallObjectMethod(user_, user::GetMethodId(user::kLinkWithCredential), + CredentialFromImpl(credential.impl_)); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallbackWithAuthData(env_, auth_data, pending_result, future_handle, - future_api_id_, &future_data_.future_impl, - ReadSignInResult); - env_->DeleteLocalRef(pending_result); + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadSignInResult); + env->DeleteLocalRef(pending_result); } return future; } @@ -887,7 +891,7 @@ UserInternal::LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const { } Future UserInternal::LinkWithProvider_DEPRECATED( - AuthData *auth_data, FederatedAuthProvider *provider) { + FederatedAuthProvider *provider) { if (!is_valid() || provider == nullptr) { SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( @@ -904,11 +908,10 @@ Future UserInternal::LinkWithProvider_DEPRECATED( } return future; } - return provider->Link(auth_data, this); + return provider->Link(auth_data_, this); } -Future UserInternal::Unlink_DEPRECATED(AuthData *auth_data, - const char *provider) { +Future UserInternal::Unlink_DEPRECATED(const char *provider) { MutexLock user_info_lock(user_mutex_); SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc(kUserFn_Unlink_DEPRECATED); @@ -920,17 +923,17 @@ Future UserInternal::Unlink_DEPRECATED(AuthData *auth_data, return future; } - jstring j_provider = env_->NewStringUTF(provider); - jobject pending_result = env_->CallObjectMethod( + JNIEnv *env = Env(auth_data_); + jstring j_provider = env->NewStringUTF(provider); + jobject pending_result = env->CallObjectMethod( user_, user::GetMethodId(user::kUnlink), j_provider); - env_->DeleteLocalRef(j_provider); + env->DeleteLocalRef(j_provider); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallbackWithAuthData(env_, auth_data, pending_result, future_handle, - future_api_id_, &future_data_.future_impl, - ReadUserFromSignInResult); - env_->DeleteLocalRef(pending_result); + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadUserFromSignInResult); + env->DeleteLocalRef(pending_result); } return future; } @@ -941,7 +944,7 @@ Future UserInternal::UnlinkLastResult_DEPRECATED() const { } Future UserInternal::UpdatePhoneNumberCredential_DEPRECATED( - AuthData *auth_data, const Credential &credential) { + const Credential &credential) { MutexLock user_info_lock(user_mutex_); SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( @@ -954,18 +957,19 @@ Future UserInternal::UpdatePhoneNumberCredential_DEPRECATED( return future; } + JNIEnv *env = Env(auth_data_); jobject j_credential = CredentialFromImpl(credential.impl_); - if (env_->IsInstanceOf(j_credential, phonecredential::GetClass())) { - jobject pending_result = env_->CallObjectMethod( + if (env->IsInstanceOf(j_credential, phonecredential::GetClass())) { + jobject pending_result = env->CallObjectMethod( user_, user::GetMethodId(user::kUpdatePhoneNumberCredential), j_credential); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallbackWithAuthData( - env_, auth_data, pending_result, future_handle, future_api_id_, - &future_data_.future_impl, ReadUserFromSignInResult); - env_->DeleteLocalRef(pending_result); + RegisterCallback(auth_data_, pending_result, future_handle, + future_api_id_, &future_data_.future_impl, + ReadUserFromSignInResult); + env->DeleteLocalRef(pending_result); } } else { CompleteFuture(kAuthErrorInvalidCredential, kInvalidCredentialErrorMessage, @@ -993,14 +997,15 @@ Future UserInternal::Reload() { future_data_.future_impl.SafeAlloc(kUserFn_Reload); Future future = MakeFuture(&future_data_.future_impl, future_handle); + JNIEnv *env = Env(auth_data_); jobject pending_result = - env_->CallObjectMethod(user_, user::GetMethodId(user::kReload)); + env->CallObjectMethod(user_, user::GetMethodId(user::kReload)); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallback(env_, pending_result, future_handle, future_api_id_, + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, &future_data_.future_impl, nullptr); - env_->DeleteLocalRef(pending_result); + env->DeleteLocalRef(pending_result); } return future; } @@ -1022,15 +1027,16 @@ Future UserInternal::Reauthenticate(const Credential &credential) { future_data_.future_impl.SafeAlloc(kUserFn_Reload); Future future = MakeFuture(&future_data_.future_impl, future_handle); + JNIEnv *env = Env(auth_data_); jobject pending_result = - env_->CallObjectMethod(user_, user::GetMethodId(user::kReauthenticate), - CredentialFromImpl(credential.impl_)); + env->CallObjectMethod(user_, user::GetMethodId(user::kReauthenticate), + CredentialFromImpl(credential.impl_)); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallback(env_, pending_result, future_handle, future_api_id_, + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, &future_data_.future_impl, nullptr); - env_->DeleteLocalRef(pending_result); + env->DeleteLocalRef(pending_result); } return future; } @@ -1041,7 +1047,7 @@ Future UserInternal::ReauthenticateLastResult() const { } Future UserInternal::ReauthenticateAndRetrieveData_DEPRECATED( - AuthData *auth_data, const Credential &credential) { + const Credential &credential) { SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); @@ -1053,16 +1059,16 @@ Future UserInternal::ReauthenticateAndRetrieveData_DEPRECATED( return future; } - jobject pending_result = env_->CallObjectMethod( + JNIEnv *env = Env(auth_data_); + jobject pending_result = env->CallObjectMethod( user_, user::GetMethodId(user::kReauthenticateAndRetrieveData), CredentialFromImpl(credential.impl_)); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallbackWithAuthData(env_, auth_data, pending_result, future_handle, - future_api_id_, &future_data_.future_impl, - ReadSignInResult); - env_->DeleteLocalRef(pending_result); + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadSignInResult); + env->DeleteLocalRef(pending_result); } return future; } @@ -1075,7 +1081,7 @@ UserInternal::ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const { } Future UserInternal::ReauthenticateWithProvider_DEPRECATED( - AuthData *auth_data, FederatedAuthProvider *provider) { + FederatedAuthProvider *provider) { if (!is_valid() || provider == nullptr) { SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( @@ -1092,10 +1098,10 @@ Future UserInternal::ReauthenticateWithProvider_DEPRECATED( } return future; } - return provider->Reauthenticate(auth_data, this); + return provider->Reauthenticate(auth_data_, this); } -Future UserInternal::Delete(AuthData *auth_data) { +Future UserInternal::Delete() { MutexLock user_info_lock(user_mutex_); if (!is_valid()) { return CreateAndCompleteFuture(kUserFn_Delete, kAuthErrorInvalidUser, @@ -1107,20 +1113,21 @@ Future UserInternal::Delete(AuthData *auth_data) { future_data_.future_impl.SafeAlloc(kUserFn_Reload); Future future = MakeFuture(&future_data_.future_impl, future_handle); + JNIEnv *env = Env(auth_data_); jobject pending_result = - env_->CallObjectMethod(user_, user::GetMethodId(user::kDelete)); + env->CallObjectMethod(user_, user::GetMethodId(user::kDelete)); - if (!CheckAndCompleteFutureOnError(env_, &future_data_.future_impl, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, future_handle)) { - RegisterCallback(env_, pending_result, future_handle, future_api_id_, + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, &future_data_.future_impl, [](jobject result, FutureCallbackData *d, bool success, void *void_data) { if (success) { - UpdateCurrentUser(d->auth_data); + UpdateCurrentUser(Env(d->auth_data), d->auth_data); } }); - env_->DeleteLocalRef(pending_result); + env->DeleteLocalRef(pending_result); } return future; } @@ -1134,20 +1141,21 @@ UserMetadata UserInternal::metadata() const { UserMetadata user_metadata; if (!is_valid()) return user_metadata; + JNIEnv *env = Env(auth_data_); jobject jUserMetadata = - env_->CallObjectMethod(user_, user::GetMethodId(user::kGetMetadata)); - util::CheckAndClearJniExceptions(env_); + env->CallObjectMethod(user_, user::GetMethodId(user::kGetMetadata)); + util::CheckAndClearJniExceptions(env); if (!jUserMetadata) return user_metadata; - user_metadata.last_sign_in_timestamp = env_->CallLongMethod( + user_metadata.last_sign_in_timestamp = env->CallLongMethod( jUserMetadata, metadata::GetMethodId(metadata::kGetLastSignInTimestamp)); - assert(env_->ExceptionCheck() == false); - user_metadata.creation_timestamp = env_->CallLongMethod( + assert(env->ExceptionCheck() == false); + user_metadata.creation_timestamp = env->CallLongMethod( jUserMetadata, metadata::GetMethodId(metadata::kGetCreationTimestamp)); - assert(env_->ExceptionCheck() == false); + assert(env->ExceptionCheck() == false); - env_->DeleteLocalRef(jUserMetadata); + env->DeleteLocalRef(jUserMetadata); return user_metadata; } @@ -1155,99 +1163,87 @@ UserMetadata UserInternal::metadata() const { bool UserInternal::is_email_verified() const { if (!is_valid()) return false; - bool result = env_->CallBooleanMethod( + JNIEnv *env = Env(auth_data_); + bool result = env->CallBooleanMethod( user_, userinfo::GetMethodId(userinfo::kIsEmailVerified)); - util::CheckAndClearJniExceptions(env_); + util::CheckAndClearJniExceptions(env); return result; } bool UserInternal::is_anonymous() const { if (!is_valid()) return false; + JNIEnv *env = Env(auth_data_); bool result = - env_->CallBooleanMethod(user_, user::GetMethodId(user::kIsAnonymous)); - util::CheckAndClearJniExceptions(env_); + env->CallBooleanMethod(user_, user::GetMethodId(user::kIsAnonymous)); + util::CheckAndClearJniExceptions(env); return result; } -#if 0 -std::string GetUserProperty(userinfo::Method method_id, - PropertyType type = kPropertyTypeString) { - jobject property = user_info_ - ? env_->CallObjectMethod( - user_info_, userinfo::GetMethodId(method_id)) - : nullptr; - if (firebase::util::CheckAndClearJniExceptions(env) || !property) { - return std::string(); - } - if (type == kPropertyTypeUri) { - return JniUriToString(env_, property); - } else { - // type == kPropertyTypeString - return JniStringToString(env_, property); - } - } -} -#endif - std::string UserInternal::uid() const { if (!is_valid()) return ""; + JNIEnv *env = Env(auth_data_); jobject property = - env_->CallObjectMethod(user_, userinfo::GetMethodId(userinfo::kGetUid)); - if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + env->CallObjectMethod(user_, userinfo::GetMethodId(userinfo::kGetUid)); + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { return std::string(); } - return JniStringToString(env_, property); + return JniStringToString(env, property); } std::string UserInternal::email() const { if (!is_valid()) return ""; + JNIEnv *env = Env(auth_data_); jobject property = - env_->CallObjectMethod(user_, userinfo::GetMethodId(userinfo::kGetEmail)); - if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + env->CallObjectMethod(user_, userinfo::GetMethodId(userinfo::kGetEmail)); + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { return std::string(); } - return JniStringToString(env_, property); + return JniStringToString(env, property); } std::string UserInternal::display_name() const { if (!is_valid()) return ""; - jobject property = env_->CallObjectMethod( + JNIEnv *env = Env(auth_data_); + jobject property = env->CallObjectMethod( user_, userinfo::GetMethodId(userinfo::kGetDisplayName)); - if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { return std::string(); } - return JniStringToString(env_, property); + return JniStringToString(env, property); } std::string UserInternal::photo_url() const { if (!is_valid()) return ""; - jobject property = env_->CallObjectMethod( + JNIEnv *env = Env(auth_data_); + jobject property = env->CallObjectMethod( user_, userinfo::GetMethodId(userinfo::kGetPhotoUrl)); - if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { return std::string(); } - return JniUriToString(env_, property); + return JniUriToString(env, property); } std::string UserInternal::provider_id() const { if (!is_valid()) return ""; - jobject property = env_->CallObjectMethod( + JNIEnv *env = Env(auth_data_); + jobject property = env->CallObjectMethod( user_, userinfo::GetMethodId(userinfo::kGetProviderId)); - if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { return std::string(); } - return JniStringToString(env_, property); + return JniStringToString(env, property); } std::string UserInternal::phone_number() const { if (!is_valid()) return ""; - jobject property = env_->CallObjectMethod( + JNIEnv *env = Env(auth_data_); + jobject property = env->CallObjectMethod( user_, userinfo::GetMethodId(userinfo::kGetPhoneNumber)); - if (firebase::util::CheckAndClearJniExceptions(env_) || !property) { + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { return std::string(); } - return JniStringToString(env_, property); + return JniStringToString(env, property); } } // namespace auth diff --git a/auth/src/common.h b/auth/src/common.h index 19038dcc4e..fee8b35458 100644 --- a/auth/src/common.h +++ b/auth/src/common.h @@ -127,9 +127,6 @@ void NotifyAuthStateListeners(AuthData* auth_data); // Notify all the listeners of the ID token change. void NotifyIdTokenListeners(AuthData* auth_data); -// Synchronize the current user. -void UpdateCurrentUser(AuthData* auth_data); - // Get a FutureImpl to use for Credential methods that return Futures. ReferenceCountedFutureImpl* GetCredentialFutureImpl(); diff --git a/auth/src/data.h b/auth/src/data.h index 54a09264c7..ac96b3d8f1 100644 --- a/auth/src/data.h +++ b/auth/src/data.h @@ -39,6 +39,9 @@ struct AuthDataDeprecatedFields { // pointer the platform specific user object, which is updated on User // operations. UserInternal* user_internal_deprecated; + + // JNI reference to the user object in the Firebase Android SDK. + void* android_user_impl; }; // Enumeration for API functions that return a Future. diff --git a/auth/src/ios/common_ios.h b/auth/src/ios/common_ios.h index 71ccaf304e..1013649ad5 100644 --- a/auth/src/ios/common_ios.h +++ b/auth/src/ios/common_ios.h @@ -48,6 +48,9 @@ OBJ_C_PTR_WRAPPER(FIRAuthCredential); OBJ_C_PTR_WRAPPER(FIRUser); OBJ_C_PTR_WRAPPER(FIRCPPAuthListenerHandle); +// Synchronize the current user. +void UpdateCurrentUser(AuthData *auth_data); + // Auth implementation on iOS. struct AuthDataIos { FIRAuthPointer fir_auth; diff --git a/auth/src/ios/user_ios.mm b/auth/src/ios/user_ios.mm index 98d58fd757..66e89120a8 100644 --- a/auth/src/ios/user_ios.mm +++ b/auth/src/ios/user_ios.mm @@ -532,11 +532,9 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { [user_ linkWithCredential:CredentialFromImpl(credential.impl_) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - NSLog(@"DEDB Completion auth_result: %p error: %p\n", auth_result, error); SignInResultCallback(auth_result, error, callback_data->future_handle, callback_data->future_data->future_impl, auth_data); - NSLog(@"DEDB Completion SignInResultCallback returned\n"); - // delete callback_data; + delete callback_data; }]; return future; } From ab8098ba3471798ddc22fbae38c17651cfcbac4c Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Sun, 26 Mar 2023 19:38:36 -0400 Subject: [PATCH 10/14] Mutex locking on most user actions --- auth/src/android/auth_android.cc | 36 ++++++++++++--- auth/src/android/common_android.h | 4 -- auth/src/android/user_android.cc | 19 ++++---- auth/src/auth.cc | 74 ++++++++++++++++++------------- auth/src/data.h | 5 ++- auth/src/desktop/user_desktop.cc | 2 +- auth/src/ios/auth_ios.mm | 19 ++++++-- auth/src/ios/common_ios.h | 4 -- auth/src/ios/user_ios.mm | 15 ++++--- 9 files changed, 111 insertions(+), 67 deletions(-) diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index 3b90161cfc..aec9687cc8 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -274,6 +274,8 @@ void Auth::InitPlatformAuth(AuthData* auth_data) { } void Auth::DestroyPlatformAuth(AuthData* auth_data) { + // Note: auth_data->auth_mutex is already locked by Auth::DeleteInternal(). + // Remove references from listener blocks. JNIEnv* env = Env(auth_data); util::CancelCallbacks(env, auth_data->future_api_id.c_str()); @@ -389,6 +391,8 @@ static void ReadProviderResult( Future Auth::FetchProvidersForEmail( const char* email) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc( kAuthFn_FetchProvidersForEmail); @@ -409,6 +413,8 @@ Future Auth::FetchProvidersForEmail( } Future Auth::SignInWithCustomToken_DEPRECATED(const char* token) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl& futures = auth_data_->future_impl; SafeFutureHandle future_handle = auth_data_->future_impl.SafeAlloc( @@ -433,6 +439,8 @@ Future Auth::SignInWithCustomToken_DEPRECATED(const char* token) { Future Auth::SignInWithCredential_DEPRECATED( const Credential& credential) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED); @@ -459,6 +467,8 @@ Future Auth::SignInWithCredential_DEPRECATED( Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential& credential) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); const auto future_handle = auth_data_->future_impl.SafeAlloc( kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED); JNIEnv* env = Env(auth_data_); @@ -485,15 +495,18 @@ Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( Future Auth::SignInWithProvider_DEPRECATED( FederatedAuthProvider* provider) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); FIREBASE_ASSERT_RETURN(Future(), provider); + MutexLock(auth_data_->auth_mutex); return provider->SignIn(auth_data_); } Future Auth::SignInAnonymously_DEPRECATED() { const auto handle = auth_data_->future_impl.SafeAlloc( kAuthFn_SignInAnonymously_DEPRECATED); + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); JNIEnv* env = Env(auth_data_); - jobject pending_result = env->CallObjectMethod( AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInAnonymously)); @@ -509,6 +522,8 @@ Future Auth::SignInAnonymously_DEPRECATED() { Future Auth::SignInWithEmailAndPassword_DEPRECATED( const char* email, const char* password) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED); @@ -543,6 +558,8 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED( Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( const char* email, const char* password) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); const auto future_handle = auth_data_->future_impl.SafeAlloc( kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED); @@ -579,9 +596,8 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( // holds nothing but a pointer to AuthData, which never changes. // All User functions that require synchronization go through AuthData's mutex. User* Auth::current_user_DEPRECATED() { - if (!auth_data_) return nullptr; - MutexLock lock(auth_data_->future_impl.mutex()); - + FIREBASE_ASSERT_RETURN(nullptr, auth_data_); + MutexLock lock(auth_data_->auth_mutex); if (auth_data_->deprecated_fields.user_deprecated == nullptr || !auth_data_->deprecated_fields.user_deprecated->is_valid()) { return nullptr; @@ -591,7 +607,8 @@ User* Auth::current_user_DEPRECATED() { } std::string Auth::language_code() const { - if (!auth_data_) return std::string(); + FIREBASE_ASSERT_RETURN(std::string(), auth_data_); + MutexLock(auth_data_->auth_mutex); JNIEnv* env = Env(auth_data_); jobject j_pending_result = env->CallObjectMethod( AuthImpl(auth_data_), auth::GetMethodId(auth::kGetLanguageCode)); @@ -603,7 +620,8 @@ std::string Auth::language_code() const { } void Auth::set_language_code(const char* language_code) { - if (!auth_data_) return; + FIREBASE_ASSERT_RETURN_VOID(auth_data_); + MutexLock(auth_data_->auth_mutex); JNIEnv* env = Env(auth_data_); jstring j_language_code = nullptr; if (language_code != nullptr) { @@ -619,7 +637,7 @@ void Auth::set_language_code(const char* language_code) { } void Auth::UseAppLanguage() { - if (!auth_data_) return; + FIREBASE_ASSERT_RETURN_VOID(auth_data_); JNIEnv* env = Env(auth_data_); env->CallVoidMethod(AuthImpl(auth_data_), auth::GetMethodId(auth::kUseAppLanguage)); @@ -627,6 +645,8 @@ void Auth::UseAppLanguage() { } void Auth::SignOut() { + FIREBASE_ASSERT_RETURN_VOID(auth_data_); + MutexLock(auth_data_->auth_mutex); JNIEnv* env = Env(auth_data_); env->CallVoidMethod(AuthImpl(auth_data_), auth::GetMethodId(auth::kSignOut)); firebase::util::CheckAndClearJniExceptions(env); @@ -639,6 +659,8 @@ void Auth::SignOut() { } Future Auth::SendPasswordResetEmail(const char* email) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SendPasswordResetEmail); diff --git a/auth/src/android/common_android.h b/auth/src/android/common_android.h index cb8a9a2dc3..a54ba0d586 100644 --- a/auth/src/android/common_android.h +++ b/auth/src/android/common_android.h @@ -172,10 +172,6 @@ class UserInternal { // Used to support older method invocation of provider_data_DEPRECATED(). std::vector user_infos_; - // Guard the creation and deletion of the vector of UserInfoInterface* - // allocations in provider_data_DEPRECATED(). - Mutex user_info_mutex_deprecated_; - // Guard against changes to the user_ object. Mutex user_mutex_; diff --git a/auth/src/android/user_android.cc b/auth/src/android/user_android.cc index 69d81d0de9..fc6e644273 100644 --- a/auth/src/android/user_android.cc +++ b/auth/src/android/user_android.cc @@ -500,19 +500,16 @@ UserInternal::~UserInternal() { JNIEnv *env = Env(auth_data_); util::CancelCallbacks(env, future_api_id_.c_str()); - env->DeleteGlobalRef(user_); - user_ = nullptr; - - { - MutexLock user_info_lock(user_info_mutex_deprecated_); - clear_user_infos(); - } - // Make sure we don't have any pending futures in flight before we disappear. while (!future_data_.future_impl.IsSafeToDelete()) { internal::Sleep(100); } + + env->DeleteGlobalRef(user_); + user_ = nullptr; auth_data_ = nullptr; + + clear_user_infos(); } void UserInternal::set_native_user_object_deprecated(jobject user) { @@ -613,7 +610,7 @@ std::vector UserInternal::provider_data() const { const std::vector &UserInternal::provider_data_DEPRECATED() { - MutexLock user_info_lock(user_info_mutex_deprecated_); + MutexLock user_info_lock(user_mutex_); clear_user_infos(); if (is_valid()) { JNIEnv *env = Env(auth_data_); @@ -858,6 +855,7 @@ Future UserInternal::LinkWithCredentialLastResult_DEPRECATED() const { Future UserInternal::LinkAndRetrieveDataWithCredential_DEPRECATED( const Credential &credential) { + MutexLock user_info_lock(user_mutex_); SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED); @@ -892,6 +890,7 @@ UserInternal::LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const { Future UserInternal::LinkWithProvider_DEPRECATED( FederatedAuthProvider *provider) { + MutexLock user_info_lock(user_mutex_); if (!is_valid() || provider == nullptr) { SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( @@ -1048,6 +1047,7 @@ Future UserInternal::ReauthenticateLastResult() const { Future UserInternal::ReauthenticateAndRetrieveData_DEPRECATED( const Credential &credential) { + MutexLock user_info_lock(user_mutex_); SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); @@ -1082,6 +1082,7 @@ UserInternal::ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const { Future UserInternal::ReauthenticateWithProvider_DEPRECATED( FederatedAuthProvider *provider) { + MutexLock user_info_lock(user_mutex_); if (!is_valid() || provider == nullptr) { SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( diff --git a/auth/src/auth.cc b/auth/src/auth.cc index a7bd564e53..40680df32c 100644 --- a/auth/src/auth.cc +++ b/auth/src/auth.cc @@ -134,48 +134,55 @@ Auth::Auth(App* app, void* auth_impl) : auth_data_(new AuthData) { } void Auth::DeleteInternal() { - MutexLock lock(*g_auths_mutex); + // Mutex is contained within the auth_data_ object. Retain a pointer to it so + // that we can clean up its contents and then delete it after we leave the + // mutex. + AuthData* retained_auth_impl = auth_data_; + { + MutexLock(auth_data_->auth_mutex); + MutexLock lock(*g_auths_mutex); - if (!auth_data_) return; + if (!auth_data_) return; - { - MutexLock destructing_lock(auth_data_->desctruting_mutex); - auth_data_->destructing = true; - } + { + MutexLock destructing_lock(auth_data_->destructing_mutex); + auth_data_->destructing = true; + } - CleanupNotifier* notifier = CleanupNotifier::FindByOwner(auth_data_->app); - assert(notifier); - notifier->UnregisterObject(this); + CleanupNotifier* notifier = CleanupNotifier::FindByOwner(auth_data_->app); + assert(notifier); + notifier->UnregisterObject(this); - int num_auths_remaining = 0; - { - // Remove `this` from the g_auths map. - // The mapping is 1:1, so we should only ever delete one. - for (auto it = g_auths.begin(); it != g_auths.end(); ++it) { - if (it->second == this) { - LogDebug("Deleting Auth %p for App %p", this, it->first); - g_auths.erase(it); - break; + int num_auths_remaining = 0; + { + // Remove `this` from the g_auths map. + // The mapping is 1:1, so we should only ever delete one. + for (auto it = g_auths.begin(); it != g_auths.end(); ++it) { + if (it->second == this) { + LogDebug("Deleting Auth %p for App %p", this, it->first); + g_auths.erase(it); + break; + } } - } - num_auths_remaining = g_auths.size(); - } + num_auths_remaining = g_auths.size(); + } - auth_data_->ClearListeners(); + auth_data_->ClearListeners(); - // If this is the last Auth instance to be cleaned up, also clean up data for - // Credentials. - if (num_auths_remaining == 0) { - CleanupCredentialFutureImpl(); - } + // If this is the last Auth instance to be cleaned up, also clean up data + // for Credentials. + if (num_auths_remaining == 0) { + CleanupCredentialFutureImpl(); + } - // Destroy the platform-specific object. - DestroyPlatformAuth(auth_data_); + // Destroy the platform-specific object. + DestroyPlatformAuth(auth_data_); + auth_data_ = nullptr; + } // Delete the pimpl data. - delete auth_data_; - auth_data_ = nullptr; + delete retained_auth_impl; } Auth::~Auth() { DeleteInternal(); } @@ -183,6 +190,7 @@ Auth::~Auth() { DeleteInternal(); } // Always non-nullptr since set in constructor. App& Auth::app() { FIREBASE_ASSERT(auth_data_ != nullptr); + MutexLock(auth_data_->auth_mutex); return *auth_data_->app; } @@ -217,6 +225,7 @@ static bool AddListener(T listener, std::vector* listener_vector, Auth* auth, void Auth::AddAuthStateListener(AuthStateListener* listener) { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); // Would have to lock mutex till the method ends to protect on race // conditions. MutexLock lock(auth_data_->listeners_mutex); @@ -235,6 +244,7 @@ void Auth::AddAuthStateListener(AuthStateListener* listener) { void Auth::AddIdTokenListener(IdTokenListener* listener) { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); // Would have to lock mutex till the method ends to protect on race // conditions. MutexLock lock(auth_data_->listeners_mutex); @@ -289,12 +299,14 @@ static void RemoveListener(T listener, std::vector* listener_vector, void Auth::RemoveAuthStateListener(AuthStateListener* listener) { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); RemoveListener(listener, &auth_data_->listeners, this, &listener->auths_, &auth_data_->listeners_mutex); } void Auth::RemoveIdTokenListener(IdTokenListener* listener) { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); int listener_count = auth_data_->id_token_listeners.size(); RemoveListener(listener, &auth_data_->id_token_listeners, this, &listener->auths_, &auth_data_->listeners_mutex); diff --git a/auth/src/data.h b/auth/src/data.h index ac96b3d8f1..529355f951 100644 --- a/auth/src/data.h +++ b/auth/src/data.h @@ -198,7 +198,10 @@ struct AuthData { bool destructing; // Mutex protecting destructing - Mutex desctruting_mutex; + Mutex destructing_mutex; + + // Mutex guarding the auth object for standard API operations. + Mutex auth_mutex; // Sets if the Id Token Listener is expecting a callback. // Used to workaround an issue where the Id Token is not reset with a new one, diff --git a/auth/src/desktop/user_desktop.cc b/auth/src/desktop/user_desktop.cc index 742875103b..25d15127e2 100644 --- a/auth/src/desktop/user_desktop.cc +++ b/auth/src/desktop/user_desktop.cc @@ -511,7 +511,7 @@ void AssignLoadedData(const Future& future, AuthData* auth_data) { void HandleLoadedData(const Future& future, void* auth_data) { auto cast_auth_data = static_cast(auth_data); - MutexLock destructing_lock(cast_auth_data->desctruting_mutex); + MutexLock destructing_lock(cast_auth_data->destructing_mutex); if (cast_auth_data->destructing) { // If auth is destructing, abort. return; diff --git a/auth/src/ios/auth_ios.mm b/auth/src/ios/auth_ios.mm index 428f3ab80b..656b5c2453 100644 --- a/auth/src/ios/auth_ios.mm +++ b/auth/src/ios/auth_ios.mm @@ -149,7 +149,7 @@ explicit ListenerHandleHolder(T handle) : handle(handle) {} // Grab the user value from the iOS API and remember it locally. void UpdateCurrentUser(AuthData *auth_data) { - MutexLock lock(auth_data->future_impl.mutex()); + MutexLock(auth_data->auth_mutex); FIRUser *user = [AuthImpl(auth_data) currentUser]; SetUserImpl(auth_data, user); } @@ -202,6 +202,7 @@ void UpdateCurrentUser(AuthData *auth_data) { // Platform-specific method to destroy the wrapped Auth class. void Auth::DestroyPlatformAuth(AuthData *auth_data) { + // Note: auth_data->auth_mutex is already locked by Auth::DeleteInternal(). // Remove references from listener blocks. AuthDataIos *auth_data_ios = reinterpret_cast(auth_data->auth_impl); FIRCPPAuthListenerHandle *listener_cpp_handle = auth_data_ios->listener_handle.get(); @@ -243,6 +244,7 @@ void LogHeartbeat(Auth *auth) { } Future Auth::FetchProvidersForEmail(const char *email) { + MutexLock(auth_data_->auth_mutex); // Create data structure to hold asynchronous results. FetchProvidersResult initial_data; @@ -275,7 +277,7 @@ void LogHeartbeat(Auth *auth) { // window. User *Auth::current_user_DEPRECATED() { if (!auth_data_) return nullptr; - MutexLock lock(auth_data_->future_impl.mutex()); + MutexLock(auth_data_->auth_mutex); if (auth_data_->deprecated_fields.user_deprecated == nullptr || !auth_data_->deprecated_fields.user_deprecated->is_valid()) { return nullptr; @@ -286,7 +288,7 @@ void LogHeartbeat(Auth *auth) { static User *AssignUser(FIRUser *_Nullable user, AuthData *auth_data) { // Update our pointer to the iOS user that we're wrapping. - MutexLock lock(auth_data->future_impl.mutex()); + MutexLock(auth_data->auth_mutex); if (user) { SetUserImpl(auth_data, user); } @@ -296,6 +298,7 @@ void LogHeartbeat(Auth *auth) { std::string Auth::language_code() const { if (!auth_data_) return ""; + MutexLock(auth_data_->auth_mutex); NSString *language_code = [AuthImpl(auth_data_) languageCode]; if (language_code == nil) { return std::string(); @@ -306,6 +309,7 @@ void LogHeartbeat(Auth *auth) { void Auth::set_language_code(const char *language_code) { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); NSString *code; if (language_code != nullptr) { code = [NSString stringWithUTF8String:language_code]; @@ -315,6 +319,7 @@ void LogHeartbeat(Auth *auth) { void Auth::UseAppLanguage() { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); [AuthImpl(auth_data_) useAppLanguage]; } @@ -381,6 +386,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu } Future Auth::SignInWithCustomToken_DEPRECATED(const char *token) { + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED, nullptr); @@ -394,6 +400,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu } Future Auth::SignInWithCredential_DEPRECATED(const Credential &credential) { + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED, nullptr); @@ -408,6 +415,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential &credential) { + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc( kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED, SignInResult()); @@ -427,6 +435,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu } Future Auth::SignInAnonymously_DEPRECATED() { + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = auth_data_->future_impl.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED, nullptr); @@ -441,6 +450,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED, nullptr); @@ -461,6 +471,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED, nullptr); @@ -480,6 +491,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu } void Auth::SignOut() { + MutexLock(auth_data_->auth_mutex); // TODO(jsanmiya): Verify with iOS team why this returns an error. NSError *_Nullable error; [AuthImpl(auth_data_) signOut:&error]; @@ -487,6 +499,7 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu } Future Auth::SendPasswordResetEmail(const char *email) { + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl &futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SendPasswordResetEmail); diff --git a/auth/src/ios/common_ios.h b/auth/src/ios/common_ios.h index 1013649ad5..4f9f655218 100644 --- a/auth/src/ios/common_ios.h +++ b/auth/src/ios/common_ios.h @@ -163,10 +163,6 @@ class UserInternal { // Used to support older method invocation of provider_data_DEPRECATED(). std::vector user_infos_; - // Guard the creation and deletion of the vector of UserInfoInterface* - // allocations in provider_data_DEPRECATED(). - Mutex user_info_mutex_deprecated_; - // Guard against changes to the user_ object. Mutex user_mutex_; }; diff --git a/auth/src/ios/user_ios.mm b/auth/src/ios/user_ios.mm index 66e89120a8..1891331154 100644 --- a/auth/src/ios/user_ios.mm +++ b/auth/src/ios/user_ios.mm @@ -290,15 +290,13 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { : user_(user_internal.user_), future_data_(kUserFnCount) {} UserInternal::~UserInternal() { - user_ = nil; - { - MutexLock user_info_lock(user_info_mutex_deprecated_); - clear_user_infos(); - } + MutexLock user_info_lock(user_mutex_); // Make sure we don't have any pending futures in flight before we disappear. while (!future_data_.future_impl.IsSafeToDelete()) { internal::Sleep(100); } + user_ = nil; + clear_user_infos(); } void UserInternal::set_native_user_object_deprecated(FIRUser *user) { @@ -352,7 +350,7 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { } const std::vector &UserInternal::provider_data_DEPRECATED() { - MutexLock user_info_lock(user_info_mutex_deprecated_); + MutexLock user_info_lock(user_mutex_); clear_user_infos(); if (is_valid()) { NSArray> *provider_data = user_.providerData; @@ -516,6 +514,7 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { Future UserInternal::LinkAndRetrieveDataWithCredential_DEPRECATED( AuthData *auth_data, const Credential &credential) { + MutexLock user_info_lock(user_mutex_); if (!is_valid()) { SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED); @@ -546,7 +545,8 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { Future UserInternal::LinkWithProvider_DEPRECATED(AuthData *auth_data, FederatedAuthProvider *provider) { - if (!is_valid() || provider == nullptr) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid() || provider == nullptr) { SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED); Future future = MakeFuture(&future_data_.future_impl, future_handle); @@ -719,6 +719,7 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { Future UserInternal::ReauthenticateWithProvider_DEPRECATED( AuthData *auth_data, FederatedAuthProvider *provider) { + MutexLock user_info_lock(user_mutex_); if (!is_valid() || provider == nullptr) { SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( kUserFn_ReauthenticateWithProvider_DEPRECATED); From 093052bc3d53ab1d99490ecd7da4f550ee667be9 Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Mon, 27 Mar 2023 13:17:55 -0400 Subject: [PATCH 11/14] standardized future creation and future impl naming --- auth/integration_test/src/integration_test.cc | 47 +++++- auth/src/android/auth_android.cc | 6 +- auth/src/android/user_android.cc | 20 ++- auth/src/ios/auth_ios.mm | 128 ++++++++-------- auth/src/ios/credential_ios.mm | 139 +++++++++--------- auth/src/ios/user_ios.mm | 28 ++-- 6 files changed, 215 insertions(+), 153 deletions(-) diff --git a/auth/integration_test/src/integration_test.cc b/auth/integration_test/src/integration_test.cc index 3727bcab9d..0de7405094 100644 --- a/auth/integration_test/src/integration_test.cc +++ b/auth/integration_test/src/integration_test.cc @@ -99,7 +99,7 @@ class FirebaseAuthTest : public FirebaseTest { void SignOut(); // Delete the current user if it's currently signed in. - void DeleteUser(); + void DeleteUser(firebase::auth::User* user = nullptr); // Passthrough method to the base class's WaitForCompletion. bool WaitForCompletion(firebase::Future future, const char* fn, @@ -261,11 +261,15 @@ void FirebaseAuthTest::SignOut() { EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); } -void FirebaseAuthTest::DeleteUser() { - if (auth_ != nullptr && auth_->current_user_DEPRECATED() != nullptr) { - FirebaseTest::WaitForCompletion(auth_->current_user_DEPRECATED()->Delete(), - "Delete User"); - ProcessEvents(100); +void FirebaseAuthTest::DeleteUser(firebase::auth::User* user) { + if (auth_ != nullptr) { + if (user == nullptr) { + user = auth_->current_user_DEPRECATED(); + } + if (user != nullptr) { + FirebaseTest::WaitForCompletion(user->Delete(), "Delete User"); + ProcessEvents(100); + } } } @@ -454,6 +458,37 @@ TEST_F(FirebaseAuthTest, TestEmailAndPasswordSignin) { EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); } +TEST_F(FirebaseAuthTest, TestRetainUser) { + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); + firebase::auth::User anonymous_user = *auth_->current_user_DEPRECATED(); + EXPECT_EQ(anonymous_user.is_anonymous(), true); + EXPECT_EQ(anonymous_user.email().size(), 0); + + SignOut(); + + std::string email = GenerateEmailAddress(); + // Register a random email and password. This signs us in as that user. + std::string password = kTestPassword; + firebase::Future create_user_future = + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), + password.c_str()); + WaitForCompletion(create_user_future, + "CreateUserWithEmailAndPassword_DEPRECATED"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); + firebase::auth::User* email_user = auth_->current_user_DEPRECATED(); + + // Ensure the users are distinct objects. + EXPECT_EQ(anonymous_user.is_anonymous(), true); + EXPECT_EQ(email_user->is_anonymous(), false); + + EXPECT_EQ(anonymous_user.email().size(), 0); + EXPECT_NE(email_user->email().size(), 0); + + DeleteUser(); + DeleteUser(&anonymous_user); +} + TEST_F(FirebaseAuthTest, TestUpdateUserProfile) { std::string email = GenerateEmailAddress(); firebase::Future create_user = diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index aec9687cc8..a5a1614575 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -114,8 +114,6 @@ METHOD_LOOKUP_DEFINITION( JNI_ID_TOKEN_LISTENER_CALLBACK_METHODS) static int g_initialized_count = 0; -static const char* kErrorEmptyEmailPassword = - "Empty email or password are not allowed."; JNIEXPORT void JNICALL JniAuthStateListener_nativeOnAuthStateChanged( JNIEnv* env, jobject clazz, jlong callback_data); @@ -532,7 +530,7 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED( futures.Complete(handle, (!email || strlen(email) == 0) ? kAuthErrorMissingEmail : kAuthErrorMissingPassword, - kErrorEmptyEmailPassword); + kErrorEmptyEmailPasswordErrorMessage); return MakeFuture(&futures, handle); } JNIEnv* env = Env(auth_data_); @@ -568,7 +566,7 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( (!email || strlen(email) == 0) ? kAuthErrorMissingEmail : kAuthErrorMissingPassword, - kErrorEmptyEmailPassword); + kErrorEmptyEmailPasswordErrorMessage); return MakeFuture(&auth_data_->future_impl, future_handle); } JNIEnv* env = Env(auth_data_); diff --git a/auth/src/android/user_android.cc b/auth/src/android/user_android.cc index fc6e644273..9dfc927f03 100644 --- a/auth/src/android/user_android.cc +++ b/auth/src/android/user_android.cc @@ -237,6 +237,16 @@ User::User(AuthData *auth_data, UserInternal *user_internal) { } } +User::User(const User &user) { + assert(user.auth_data_); + auth_data_ = user.auth_data_; + if (user.user_internal_ != nullptr) { + user_internal_ = new UserInternal(auth_data_, user.user_internal_->user_); + } else { + user_internal_ = new UserInternal(auth_data_, nullptr); + } +} + User::~User() { delete user_internal_; user_internal_ = nullptr; @@ -252,7 +262,7 @@ User &User::operator=(const User &user) { if (user.user_internal_ != nullptr) { user_internal_ = new UserInternal(auth_data_, user.user_internal_->user_); } else { - user_internal_ = new UserInternal(user.auth_data_, nullptr); + user_internal_ = new UserInternal(auth_data_, nullptr); } return *this; @@ -490,8 +500,14 @@ UserInternal::UserInternal(AuthData *auth_data, jobject user) UserInternal::UserInternal(const UserInternal &user_internal) : auth_data_(user_internal.auth_data_), - user_(user_internal.user_), + user_(nullptr), future_data_(kUserFnCount) { + assert(auth_data_); + JNIEnv *env = Env(auth_data_); + if (user_internal.user_ != nullptr) { + user_ = env->NewGlobalRef(user_internal.user_); + assert(env->ExceptionCheck() == false); + } assign_future_id(this, &future_api_id_); } diff --git a/auth/src/ios/auth_ios.mm b/auth/src/ios/auth_ios.mm index 656b5c2453..af60ff8ac0 100644 --- a/auth/src/ios/auth_ios.mm +++ b/auth/src/ios/auth_ios.mm @@ -248,15 +248,15 @@ void LogHeartbeat(Auth *auth) { // Create data structure to hold asynchronous results. FetchProvidersResult initial_data; - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_FetchProvidersForEmail, initial_data); - + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_FetchProvidersForEmail, initial_data); + Future future = MakeFuture(&future_impl, future_handle); [AuthImpl(auth_data_) fetchSignInMethodsForEmail:@(email) completion:^(NSArray *_Nullable providers, NSError *_Nullable error) { - futures.Complete( - handle, AuthErrorFromNSError(error), + future_impl.Complete( + future_handle, AuthErrorFromNSError(error), [error.localizedDescription UTF8String], [providers](FetchProvidersResult *data) { // Copy data to our result format. @@ -267,8 +267,7 @@ void LogHeartbeat(Auth *auth) { } }); }]; - - return MakeFuture(&futures, handle); + return future; } // Support the deprecated current_user method by returning a pointer to the @@ -334,13 +333,13 @@ AuthError AuthErrorFromNSError(NSError *_Nullable error) { } void SignInCallback(FIRUser *_Nullable user, NSError *_Nullable error, - SafeFutureHandle handle, ReferenceCountedFutureImpl &future_impl, + SafeFutureHandle future_handle, ReferenceCountedFutureImpl &future_impl, AuthData *auth_data) { User *result = AssignUser(user, auth_data); - if (future_impl.ValidFuture(handle)) { + if (future_impl.ValidFuture(future_handle)) { // Finish off the asynchronous call so that the caller can read it. - future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + future_impl.CompleteWithResult(future_handle, AuthErrorFromNSError(error), util::NSStringToString(error.localizedDescription).c_str(), result); } @@ -348,16 +347,16 @@ void SignInCallback(FIRUser *_Nullable user, NSError *_Nullable error, void SignInResultWithProviderCallback( FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error, - SafeFutureHandle handle, ReferenceCountedFutureImpl &future_impl, + SafeFutureHandle future_handle, ReferenceCountedFutureImpl &future_impl, AuthData *_Nonnull auth_data, const FIROAuthProvider *_Nonnull ios_auth_provider /*unused */) { // ios_auth_provider exists as a parameter to hold a reference to the FIROAuthProvider preventing // its release by the Objective-C runtime during the asynchronous SignIn operation. error = RemapBadProviderIDErrors(error); - SignInResultCallback(auth_result, error, handle, future_impl, auth_data); + SignInResultCallback(auth_result, error, future_handle, future_impl, auth_data); } void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error, - SafeFutureHandle handle, + SafeFutureHandle future_handle, ReferenceCountedFutureImpl &future_impl, AuthData *auth_data) { User *user = AssignUser(auth_result.user, auth_data); @@ -378,8 +377,8 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu } } - if (future_impl.ValidFuture(handle)) { - future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + if (future_impl.ValidFuture(future_handle)) { + future_impl.CompleteWithResult(future_handle, AuthErrorFromNSError(error), util::NSStringToString(error.localizedDescription).c_str(), result); } @@ -387,46 +386,47 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SignInWithCustomToken_DEPRECATED(const char *token) { MutexLock(auth_data_->auth_mutex); - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED, nullptr); - + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED, nullptr); + Future future = MakeFuture(&future_impl, future_handle); [AuthImpl(auth_data_) signInWithCustomToken:@(token) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, futures, auth_data_); + SignInCallback(auth_result.user, error, future_handle, future_impl, auth_data_); }]; - return MakeFuture(&futures, handle); + return future; } Future Auth::SignInWithCredential_DEPRECATED(const Credential &credential) { MutexLock(auth_data_->auth_mutex); - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED, nullptr); - + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED, nullptr); + Future future = MakeFuture(&future_impl, future_handle); [AuthImpl(auth_data_) signInWithCredential:CredentialFromImpl(credential.impl_) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, futures, auth_data_); + SignInCallback(auth_result.user, error, future_handle, future_impl, auth_data_); }]; - return MakeFuture(&futures, handle); + return future; } Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential &credential) { MutexLock(auth_data_->auth_mutex); - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc( + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = future_impl.SafeAlloc( kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED, SignInResult()); - + Future future = MakeFuture(&future_impl, future_handle); [AuthImpl(auth_data_) signInWithCredential:CredentialFromImpl(credential.impl_) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInResultCallback(auth_result, error, handle, futures, auth_data_); + SignInResultCallback(auth_result, error, future_handle, future_impl, auth_data_); }]; - - return MakeFuture(&futures, handle); + return future; } Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider *provider) { @@ -436,58 +436,62 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SignInAnonymously_DEPRECATED() { MutexLock(auth_data_->auth_mutex); - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = auth_data_->future_impl.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED, nullptr); - + Future future = MakeFuture(&future_impl, future_handle); [AuthImpl(auth_data_) signInAnonymouslyWithCompletion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, futures, auth_data_); + SignInCallback(auth_result.user, error, future_handle, future_impl, auth_data_); }]; - - return MakeFuture(&futures, handle); + return future; } Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { MutexLock(auth_data_->auth_mutex); - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED, nullptr); + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED, nullptr); + Future future = MakeFuture(&future_impl, future_handle); if (!email || strlen(email) == 0) { - futures.Complete(handle, kAuthErrorMissingEmail, "Empty email is not allowed."); + future_impl.Complete(future_handle, kAuthErrorMissingEmail, "Empty email is not allowed."); } else if (!password || strlen(password) == 0) { - futures.Complete(handle, kAuthErrorMissingPassword, "Empty password is not allowed."); + future_impl.Complete(future_handle, kAuthErrorMissingPassword, + "Empty password is not allowed."); } else { [AuthImpl(auth_data_) signInWithEmail:@(email) password:@(password) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, futures, auth_data_); + SignInCallback(auth_result.user, error, future_handle, future_impl, auth_data_); }]; } - return MakeFuture(&futures, handle); + return future; } Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { MutexLock(auth_data_->auth_mutex); - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED, nullptr); + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED, nullptr); + Future future = MakeFuture(&future_impl, future_handle); if (!email || strlen(email) == 0) { - futures.Complete(handle, kAuthErrorMissingEmail, "Empty email is not allowed."); + future_impl.Complete(future_handle, kAuthErrorMissingEmail, + kErrorEmptyEmailPasswordErrorMessage); } else if (!password || strlen(password) == 0) { - futures.Complete(handle, kAuthErrorMissingPassword, "Empty password is not allowed."); + future_impl.Complete(future_handle, kAuthErrorMissingPassword, + kErrorEmptyEmailPasswordErrorMessage); } else { [AuthImpl(auth_data_) createUserWithEmail:@(email) password:@(password) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, futures, auth_data_); + SignInCallback(auth_result.user, error, future_handle, future_impl, auth_data_); }]; } - return MakeFuture(&futures, handle); + return future; } void Auth::SignOut() { @@ -500,16 +504,16 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu Future Auth::SendPasswordResetEmail(const char *email) { MutexLock(auth_data_->auth_mutex); - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SendPasswordResetEmail); - - [AuthImpl(auth_data_) sendPasswordResetWithEmail:@(email) - completion:^(NSError *_Nullable error) { - futures.Complete(handle, AuthErrorFromNSError(error), - [error.localizedDescription UTF8String]); - }]; - - return MakeFuture(&futures, handle); + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = future_impl.SafeAlloc(kAuthFn_SendPasswordResetEmail); + Future future = MakeFuture(&future_impl, future_handle); + [AuthImpl(auth_data_) + sendPasswordResetWithEmail:@(email) + completion:^(NSError *_Nullable error) { + future_impl.Complete(future_handle, AuthErrorFromNSError(error), + [error.localizedDescription UTF8String]); + }]; + return future; } // Remap iOS SDK errors reported by the UIDelegate. While these errors seem like diff --git a/auth/src/ios/credential_ios.mm b/auth/src/ios/credential_ios.mm index 4452574cac..5fbade9c73 100644 --- a/auth/src/ios/credential_ios.mm +++ b/auth/src/ios/credential_ios.mm @@ -170,10 +170,12 @@ @implementation PhoneListenerDataObjC // static Future GameCenterAuthProvider::GetCredential() { - auto future_api = GetCredentialFutureImpl(); - FIREBASE_ASSERT(future_api != nullptr); + ReferenceCountedFutureImpl* future_impl = GetCredentialFutureImpl(); + FIREBASE_ASSERT(future_impl != nullptr); + const auto future_handle = + future_impl->SafeAlloc(kCredentialFn_GameCenterGetCredential); + Future future = MakeFuture(future_impl, future_handle); - const auto handle = future_api->SafeAlloc(kCredentialFn_GameCenterGetCredential); /** Linking GameKit.framework without using it on macOS results in App Store rejection. Thus we don't link GameKit.framework to our SDK directly. `optionalLocalPlayer` is used for @@ -184,20 +186,19 @@ @implementation PhoneListenerDataObjC // Early-out if GameKit is not linked if (!optionalLocalPlayer) { - future_api->Complete(handle, kAuthErrorInvalidCredential, - "GameCenter authentication is unavailable - missing GameKit capability."); - return MakeFuture(future_api, handle); + future_impl->Complete(future_handle, kAuthErrorInvalidCredential, + "GameCenter authentication is unavailable - missing GameKit capability."); + } else { + [FIRGameCenterAuthProvider + getCredentialWithCompletion:^(FIRAuthCredential* _Nullable credential, + NSError* _Nullable error) { + Credential result(new FIRAuthCredentialPointer(credential)); + future_impl->CompleteWithResult( + future_handle, AuthErrorFromNSError(error), + util::NSStringToString(error.localizedDescription).c_str(), result); + }]; } - - [FIRGameCenterAuthProvider getCredentialWithCompletion:^(FIRAuthCredential* _Nullable credential, - NSError* _Nullable error) { - Credential result(new FIRAuthCredentialPointer(credential)); - future_api->CompleteWithResult(handle, AuthErrorFromNSError(error), - util::NSStringToString(error.localizedDescription).c_str(), - result); - }]; - - return MakeFuture(future_api, handle); + return future; } // static @@ -407,19 +408,19 @@ explicit PhoneAuthProviderData(FIRPhoneAuthProvider* objc_provider) // current API. void LinkWithProviderGetCredentialCallback(FIRAuthCredential* _Nullable credential, NSError* _Nullable error, - SafeFutureHandle handle, + SafeFutureHandle future_handle, ReferenceCountedFutureImpl& future_impl, AuthData* auth_data, FIRUser* user, const FIROAuthProvider* ios_auth_provider) { if (error && error.code != 0) { error = RemapBadProviderIDErrors(error); - future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + future_impl.CompleteWithResult(future_handle, AuthErrorFromNSError(error), util::NSStringToString(error.localizedDescription).c_str(), SignInResult()); } else { [user linkWithCredential:credential completion:^(FIRAuthDataResult* _Nullable auth_result, NSError* _Nullable error) { - SignInResultWithProviderCallback(auth_result, error, handle, future_impl, + SignInResultWithProviderCallback(auth_result, error, future_handle, future_impl, auth_data, ios_auth_provider); }]; } @@ -430,20 +431,20 @@ void LinkWithProviderGetCredentialCallback(FIRAuthCredential* _Nullable credenti // accessible via their current API. void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullable credential, NSError* _Nullable error, - SafeFutureHandle handle, + SafeFutureHandle future_handle, ReferenceCountedFutureImpl& future_impl, AuthData* auth_data, FIRUser* user, const FIROAuthProvider* ios_auth_provider) { if (error && error.code != 0) { error = RemapBadProviderIDErrors(error); - future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + future_impl.CompleteWithResult(future_handle, AuthErrorFromNSError(error), util::NSStringToString(error.localizedDescription).c_str(), SignInResult()); } else { [user reauthenticateWithCredential:credential completion:^(FIRAuthDataResult* _Nullable auth_result, NSError* _Nullable error) { - SignInResultWithProviderCallback(auth_result, error, handle, + SignInResultWithProviderCallback(auth_result, error, future_handle, future_impl, auth_data, ios_auth_provider); }]; @@ -452,9 +453,11 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl Future FederatedOAuthProvider::SignIn(AuthData* auth_data) { assert(auth_data); - ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_SignInWithProvider_DEPRECATED, SignInResult()); + ReferenceCountedFutureImpl& future_impl = auth_data->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_SignInWithProvider_DEPRECATED, SignInResult()); + Future future = MakeFuture(&future_impl, future_handle); + FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) auth:AuthImpl(auth_data)]; @@ -465,24 +468,25 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl signInWithProvider:ios_provider UIDelegate:nullptr completion:^(FIRAuthDataResult* _Nullable auth_result, NSError* _Nullable error) { - SignInResultWithProviderCallback(auth_result, error, handle, futures, auth_data, - ios_provider); + SignInResultWithProviderCallback(auth_result, error, future_handle, future_impl, + auth_data, ios_provider); }]; - return MakeFuture(&futures, handle); } else { - Future future = MakeFuture(&futures, handle); - futures.CompleteWithResult(handle, kAuthErrorFailure, "Internal error constructing provider.", - SignInResult()); - return future; + future_impl.CompleteWithResult(future_handle, kAuthErrorFailure, + "Internal error constructing provider.", SignInResult()); } + return future; } Future FederatedOAuthProvider::Link(AuthData* auth_data, UserInternal* user_internal) { assert(auth_data); assert(user_internal); - auto handle = user_internal->future_data_.future_impl.SafeAlloc( - kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + ReferenceCountedFutureImpl& future_impl = user_internal->future_data_.future_impl; + auto future_handle = + future_impl.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + Future future = MakeFuture(&future_impl, future_handle); + #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) @@ -493,36 +497,36 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl FIRUser* user = user_internal->user_; // TODO(b/138788092) invoke FIRUser linkWithProvider instead, once that method is added to the // iOS SDK. - [ios_provider - getCredentialWithUIDelegate:nullptr - completion:^(FIRAuthCredential* _Nullable credential, - NSError* _Nullable error) { - LinkWithProviderGetCredentialCallback( - credential, error, handle, user_internal->future_data_.future_impl, - auth_data, user, ios_provider); - }]; - return MakeFuture(&user_internal->future_data_.future_impl, handle); + [ios_provider getCredentialWithUIDelegate:nullptr + completion:^(FIRAuthCredential* _Nullable credential, + NSError* _Nullable error) { + LinkWithProviderGetCredentialCallback( + credential, error, future_handle, + user_internal->future_data_.future_impl, auth_data, user, + ios_provider); + }]; } else { - Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); - user_internal->future_data_.future_impl.CompleteWithResult( - handle, kAuthErrorFailure, "Internal error constructing provider.", SignInResult()); - return future; + future_impl.CompleteWithResult(future_handle, kAuthErrorFailure, + "Internal error constructing provider.", SignInResult()); } #else // non-iOS Apple platforms (eg: tvOS) - Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); - user_internal->future_data_.future_impl.Complete( - handle, kAuthErrorApiNotAvailable, - "OAuth provider linking is not supported on non-iOS Apple platforms."); + future_impl.CompleteWithResult( + future_handle, kAuthErrorApiNotAvailable, + "OAuth provider linking is not supported on non-iOS Apple platforms.", SignInResult()); #endif // FIREBASE_PLATFORM_IOS + return future; } Future FederatedOAuthProvider::Reauthenticate(AuthData* auth_data, UserInternal* user_internal) { assert(auth_data); assert(user_internal); - auto handle = user_internal->future_data_.future_impl.SafeAlloc( + ReferenceCountedFutureImpl& future_impl = user_internal->future_data_.future_impl; + auto future_handle = future_impl.SafeAlloc( kUserFn_ReauthenticateWithProvider_DEPRECATED, SignInResult()); + Future future = MakeFuture(&future_impl, future_handle); + #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) @@ -533,28 +537,23 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl FIRUser* user = user_internal->user_; // TODO(b/138788092) invoke FIRUser:reuthenticateWithProvider instead, once that method is added // to the iOS SDK. - [ios_provider - getCredentialWithUIDelegate:nullptr - completion:^(FIRAuthCredential* _Nullable credential, - NSError* _Nullable error) { - ReauthenticateWithProviderGetCredentialCallback( - credential, error, handle, user_internal->future_data_.future_impl, - auth_data, user, ios_provider); - }]; - return MakeFuture(&user_internal->future_data_.future_impl, handle); + [ios_provider getCredentialWithUIDelegate:nullptr + completion:^(FIRAuthCredential* _Nullable credential, + NSError* _Nullable error) { + ReauthenticateWithProviderGetCredentialCallback( + credential, error, future_handle, future_impl, auth_data, + user, ios_provider); + }]; } else { - Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); - user_internal->future_data_.future_impl.CompleteWithResult( - handle, kAuthErrorFailure, "Internal error constructing provider.", SignInResult()); - return future; + future_impl.CompleteWithResult(future_handle, kAuthErrorFailure, + "Internal error constructing provider.", SignInResult()); } - #else // non-iOS Apple platforms (eg: tvOS) - Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); - user_internal->future_data_.future_impl.Complete( - handle, kAuthErrorApiNotAvailable, - "OAuth reauthentication is not supported on non-iOS Apple platforms."); + future_impl.CompleteWithResult( + future_handle, kAuthErrorApiNotAvailable, + "OAuth reauthentication is not supported on non-iOS Apple platforms.", SignInResult()); #endif // FIREBASE_PLATFORM_IOS + return future; } } // namespace auth diff --git a/auth/src/ios/user_ios.mm b/auth/src/ios/user_ios.mm index 1891331154..6882b3e6f8 100644 --- a/auth/src/ios/user_ios.mm +++ b/auth/src/ios/user_ios.mm @@ -36,6 +36,7 @@ /// User::User(AuthData *auth_data, UserInternal *user_internal) { assert(auth_data); + auth_data_ = auth_data; if (user_internal == nullptr) { // Create an invalid user internal. // This will return is_valid() false, and operations will fail. @@ -43,7 +44,18 @@ } else { user_internal_ = user_internal; } - auth_data_ = auth_data; +} + +User::User(const User &user) { + assert(user.auth_data_); + auth_data_ = user.auth_data_; + if (user.user_internal_ == nullptr) { + // Create an invalid user internal. + // This will return is_valid() false, and operations will fail. + user_internal_ = new UserInternal(nullptr); + } else { + user_internal_ = new UserInternal(user.user_internal_->user_); + } } User::~User() { @@ -446,7 +458,6 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { [error.localizedDescription UTF8String]); delete callback_data; }]; - return future; } @@ -472,7 +483,6 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { [error.localizedDescription UTF8String]); delete callback_data; }]; - return future; } @@ -545,11 +555,12 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { Future UserInternal::LinkWithProvider_DEPRECATED(AuthData *auth_data, FederatedAuthProvider *provider) { - MutexLock user_info_lock(user_mutex_); - if (!is_valid() || provider == nullptr) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid() || provider == nullptr) { SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED); Future future = MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, future_handle, &future_data_, SignInResult()); @@ -558,8 +569,9 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { &future_data_, SignInResult()); } return future; + } else { + return provider->Link(auth_data, this); } - return provider->Link(auth_data, this); } Future UserInternal::Unlink_DEPRECATED(AuthData *auth_data, const char *provider) { @@ -621,16 +633,14 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { CompleteFuture(kAuthErrorInvalidCredential, kInvalidCredentialErrorMessage, callback_data->future_handle, &future_data_, (User *)nullptr); } - return future; - #else // non iOS Apple platforms (eg: tvOS). SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc(kUserFn_UpdatePhoneNumberCredential_DEPRECATED); Future future = MakeFuture(&future_data_.future_impl, future_handle); CompleteFuture(kAuthErrorApiNotAvailable, kPhoneAuthNotSupportedErrorMessage, future_handle, &future_data_, (User *)nullptr); - return future; #endif // FIREBASE_PLATFORM_IOS + return future; } Future UserInternal::Reload() { From eac0334c5a2c7b1e02b2f59967e419b6dd86cb47 Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Mon, 27 Mar 2023 13:18:18 -0400 Subject: [PATCH 12/14] moved error string to common implementation. --- auth/src/common.cc | 4 +++- auth/src/common.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/auth/src/common.cc b/auth/src/common.cc index e76e331457..165c8c6cfd 100644 --- a/auth/src/common.cc +++ b/auth/src/common.cc @@ -22,13 +22,15 @@ namespace firebase { namespace auth { const char* kUserNotInitializedErrorMessage = - "Operation attmpted on an invalid User object."; + "Operation attempted on an invalid User object."; const char* kPhoneAuthNotSupportedErrorMessage = "Phone Auth is not supported on this platform."; const char* kAuthInvalidParameterErrorMessage = "A parameter pass to the auth method is null or invalid."; extern const char* kInvalidCredentialErrorMessage = "The provided credential does not match the required type."; +extern const char* kErrorEmptyEmailPasswordErrorMessage = + "Empty email or password are not allowed."; // static member variables const uint32_t PhoneAuthProvider::kMaxTimeoutMs = 3000; diff --git a/auth/src/common.h b/auth/src/common.h index fee8b35458..0079c9eb61 100644 --- a/auth/src/common.h +++ b/auth/src/common.h @@ -30,6 +30,7 @@ extern const char* kUserNotInitializedErrorMessage; extern const char* kPhoneAuthNotSupportedErrorMessage; extern const char* kAuthInvalidParameterErrorMessage; extern const char* kInvalidCredentialErrorMessage; +extern const char* kErrorEmptyEmailPasswordErrorMessage; // Enumeration for Credential API functions that return a Future. // This allows us to hold a Future for the most recent call to that API. From 78a07026ca063926d74b776291b15045baeaac93 Mon Sep 17 00:00:00 2001 From: "drsanta@google.com" Date: Mon, 27 Mar 2023 13:43:34 -0400 Subject: [PATCH 13/14] removed env from SetUserImpl --- auth/src/android/auth_android.cc | 4 ++-- auth/src/android/common_android.cc | 4 ++-- auth/src/android/common_android.h | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index a5a1614575..2309152475 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -300,7 +300,7 @@ void Auth::DestroyPlatformAuth(AuthData* auth_data) { // Auth methods which return User pointer. SetImplFromLocalRef(env, nullptr, &auth_data->deprecated_fields.android_user_impl); - SetUserImpl(env, auth_data, nullptr); + SetUserImpl(auth_data, nullptr); auth_data->deprecated_fields.user_internal_deprecated = nullptr; @@ -653,7 +653,7 @@ void Auth::SignOut() { MutexLock lock(auth_data_->future_impl.mutex()); SetImplFromLocalRef(env, nullptr, &auth_data_->deprecated_fields.android_user_impl); - SetUserImpl(env, auth_data_, nullptr); + SetUserImpl(auth_data_, nullptr); } Future Auth::SendPasswordResetEmail(const char* email) { diff --git a/auth/src/android/common_android.cc b/auth/src/android/common_android.cc index f0dea43cf8..98c43d9497 100644 --- a/auth/src/android/common_android.cc +++ b/auth/src/android/common_android.cc @@ -487,7 +487,7 @@ void ReadSignInResult(jobject result, FutureCallbackData* d, // Auth class has not been updated at this point. SetImplFromLocalRef(env, j_user, &d->auth_data->deprecated_fields.android_user_impl); - SetUserImpl(env, d->auth_data, + SetUserImpl(d->auth_data, static_cast( d->auth_data->deprecated_fields.android_user_impl)); @@ -527,7 +527,7 @@ void ReadUserFromSignInResult(jobject result, FutureCallbackData* d, // Auth class has not been updated at this point. SetImplFromLocalRef(env, j_user, &d->auth_data->deprecated_fields.android_user_impl); - SetUserImpl(env, d->auth_data, + SetUserImpl(d->auth_data, static_cast( d->auth_data->deprecated_fields.android_user_impl)); } diff --git a/auth/src/android/common_android.h b/auth/src/android/common_android.h index a54ba0d586..aed4e22b55 100644 --- a/auth/src/android/common_android.h +++ b/auth/src/android/common_android.h @@ -237,8 +237,7 @@ void UpdateCurrentUser(JNIEnv* env, AuthData* auth_data); /// Note: this function is only used to support DEPRECATED methods which return /// User*. This functionality should be removed when those deprecated methods /// are removed. -inline void SetUserImpl(JNIEnv* env, AuthData* _Nonnull auth_data, - jobject j_user) { +inline void SetUserImpl(AuthData* _Nonnull auth_data, jobject j_user) { assert(auth_data->deprecated_fields.user_internal_deprecated); auth_data->deprecated_fields.user_internal_deprecated ->set_native_user_object_deprecated(j_user); From 0fd6f7b6fd854ba5047e133af22d7d2967c6391d Mon Sep 17 00:00:00 2001 From: DellaBitta Date: Mon, 27 Mar 2023 13:44:10 -0400 Subject: [PATCH 14/14] Android Auth Google I/O rework (#1245) Removes the need for User objects to be stored in AuthData, unlocking ability for there to be more than one User object at a time. Continues to store a User in Auth, though, to maintain the implementation of the newly deprecated methods which return a User*. Added a RetainUser integration test. --- auth/integration_test/src/integration_test.cc | 47 +- auth/src/android/auth_android.cc | 190 +-- auth/src/android/common_android.cc | 16 +- auth/src/android/common_android.h | 198 ++- auth/src/android/credential_android.cc | 81 +- auth/src/android/user_android.cc | 1132 ++++++++++++----- auth/src/auth.cc | 74 +- auth/src/common.cc | 8 +- auth/src/common.h | 12 +- auth/src/data.h | 8 +- auth/src/desktop/user_desktop.cc | 2 +- auth/src/include/firebase/auth/types.h | 5 +- auth/src/include/firebase/auth/user.h | 7 +- auth/src/ios/auth_ios.mm | 147 ++- auth/src/ios/common_ios.h | 17 +- auth/src/ios/credential_ios.mm | 141 +- auth/src/ios/user_ios.mm | 75 +- 17 files changed, 1501 insertions(+), 659 deletions(-) diff --git a/auth/integration_test/src/integration_test.cc b/auth/integration_test/src/integration_test.cc index 3727bcab9d..0de7405094 100644 --- a/auth/integration_test/src/integration_test.cc +++ b/auth/integration_test/src/integration_test.cc @@ -99,7 +99,7 @@ class FirebaseAuthTest : public FirebaseTest { void SignOut(); // Delete the current user if it's currently signed in. - void DeleteUser(); + void DeleteUser(firebase::auth::User* user = nullptr); // Passthrough method to the base class's WaitForCompletion. bool WaitForCompletion(firebase::Future future, const char* fn, @@ -261,11 +261,15 @@ void FirebaseAuthTest::SignOut() { EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); } -void FirebaseAuthTest::DeleteUser() { - if (auth_ != nullptr && auth_->current_user_DEPRECATED() != nullptr) { - FirebaseTest::WaitForCompletion(auth_->current_user_DEPRECATED()->Delete(), - "Delete User"); - ProcessEvents(100); +void FirebaseAuthTest::DeleteUser(firebase::auth::User* user) { + if (auth_ != nullptr) { + if (user == nullptr) { + user = auth_->current_user_DEPRECATED(); + } + if (user != nullptr) { + FirebaseTest::WaitForCompletion(user->Delete(), "Delete User"); + ProcessEvents(100); + } } } @@ -454,6 +458,37 @@ TEST_F(FirebaseAuthTest, TestEmailAndPasswordSignin) { EXPECT_EQ(auth_->current_user_DEPRECATED(), nullptr); } +TEST_F(FirebaseAuthTest, TestRetainUser) { + WaitForCompletion(auth_->SignInAnonymously_DEPRECATED(), "SignInAnonymously"); + ASSERT_NE(auth_->current_user_DEPRECATED(), nullptr); + firebase::auth::User anonymous_user = *auth_->current_user_DEPRECATED(); + EXPECT_EQ(anonymous_user.is_anonymous(), true); + EXPECT_EQ(anonymous_user.email().size(), 0); + + SignOut(); + + std::string email = GenerateEmailAddress(); + // Register a random email and password. This signs us in as that user. + std::string password = kTestPassword; + firebase::Future create_user_future = + auth_->CreateUserWithEmailAndPassword_DEPRECATED(email.c_str(), + password.c_str()); + WaitForCompletion(create_user_future, + "CreateUserWithEmailAndPassword_DEPRECATED"); + EXPECT_NE(auth_->current_user_DEPRECATED(), nullptr); + firebase::auth::User* email_user = auth_->current_user_DEPRECATED(); + + // Ensure the users are distinct objects. + EXPECT_EQ(anonymous_user.is_anonymous(), true); + EXPECT_EQ(email_user->is_anonymous(), false); + + EXPECT_EQ(anonymous_user.email().size(), 0); + EXPECT_NE(email_user->email().size(), 0); + + DeleteUser(); + DeleteUser(&anonymous_user); +} + TEST_F(FirebaseAuthTest, TestUpdateUserProfile) { std::string email = GenerateEmailAddress(); firebase::Future create_user = diff --git a/auth/src/android/auth_android.cc b/auth/src/android/auth_android.cc index 4691b3ada6..a5a1614575 100644 --- a/auth/src/android/auth_android.cc +++ b/auth/src/android/auth_android.cc @@ -114,8 +114,6 @@ METHOD_LOOKUP_DEFINITION( JNI_ID_TOKEN_LISTENER_CALLBACK_METHODS) static int g_initialized_count = 0; -static const char* kErrorEmptyEmailPassword = - "Empty email or password are not allowed."; JNIEXPORT void JNICALL JniAuthStateListener_nativeOnAuthStateChanged( JNIEnv* env, jobject clazz, jlong callback_data); @@ -162,27 +160,20 @@ void ReleaseAuthClasses(JNIEnv* env) { jni_id_token_listener::ReleaseClass(env); } -void UpdateCurrentUser(AuthData* auth_data) { - JNIEnv* env = Env(auth_data); - +// Grab the user value from the Android SDK and remember it locally. +void UpdateCurrentUser(JNIEnv* env, AuthData* auth_data) { MutexLock lock(auth_data->future_impl.mutex()); - - const void* original_user_impl = auth_data->user_impl; - // Update our pointer to the Android FirebaseUser that we're wrapping. jobject j_user = env->CallObjectMethod( AuthImpl(auth_data), auth::GetMethodId(auth::kGetCurrentUser)); if (firebase::util::CheckAndClearJniExceptions(env)) { j_user = nullptr; } - SetImplFromLocalRef(env, j_user, &auth_data->user_impl); - - // Log debug message when user sign-in status has changed. - if (original_user_impl != auth_data->user_impl) { - LogDebug("CurrentUser changed from %X to %X", - reinterpret_cast(original_user_impl), - reinterpret_cast(auth_data->user_impl)); - } + SetImplFromLocalRef(env, j_user, + &auth_data->deprecated_fields.android_user_impl); + SetUserImpl( + env, auth_data, + static_cast(auth_data->deprecated_fields.android_user_impl)); } // Release cached Java classes. @@ -237,6 +228,15 @@ void* CreatePlatformAuth(App* app) { void Auth::InitPlatformAuth(AuthData* auth_data) { JNIEnv* env = Env(auth_data); + // Create persistent User data to continue to facilitate deprecated aysnc + // methods which return a pointer to a User. Remove this structure when those + // deprecated methods are removed. + auth_data->deprecated_fields.android_user_impl = (jobject) nullptr; + auth_data->deprecated_fields.user_internal_deprecated = + new UserInternal(auth_data, (jobject) nullptr); + auth_data->deprecated_fields.user_deprecated = new User( + auth_data, auth_data->deprecated_fields.user_internal_deprecated); + // Create the JniAuthStateListener class to redirect the state-change // from Java to C++. jobject j_listener = @@ -268,10 +268,12 @@ void Auth::InitPlatformAuth(AuthData* auth_data) { // Ensure our User is in-line with underlying API's user. // It's possible for a user to already be logged-in on start-up. - UpdateCurrentUser(auth_data); + UpdateCurrentUser(env, auth_data); } void Auth::DestroyPlatformAuth(AuthData* auth_data) { + // Note: auth_data->auth_mutex is already locked by Auth::DeleteInternal(). + // Remove references from listener blocks. JNIEnv* env = Env(auth_data); util::CancelCallbacks(env, auth_data->future_api_id.c_str()); @@ -294,11 +296,23 @@ void Auth::DestroyPlatformAuth(AuthData* auth_data) { static_cast(auth_data->id_token_listener_impl)); assert(env->ExceptionCheck() == false); - // Deleting our global references should trigger the FirebaseAuth class and - // FirebaseUser Java objects to be deleted. + // Clear the retained User object, which is used to support those deprecated + // Auth methods which return User pointer. + SetImplFromLocalRef(env, nullptr, + &auth_data->deprecated_fields.android_user_impl); + SetUserImpl(env, auth_data, nullptr); + + auth_data->deprecated_fields.user_internal_deprecated = nullptr; + + // This also deletes auth_data->deprecated_fields.user_internal_deprecated + // since User has ownership of the UserInternal allocation. + delete auth_data->deprecated_fields.user_deprecated; + auth_data->deprecated_fields.user_deprecated = nullptr; + + // Deleting our global references should trigger the FirebaseAuth class to be + // deleted. SetImplFromLocalRef(env, nullptr, &auth_data->listener_impl); SetImplFromLocalRef(env, nullptr, &auth_data->id_token_listener_impl); - SetImplFromLocalRef(env, nullptr, &auth_data->user_impl); SetImplFromLocalRef(env, nullptr, &auth_data->auth_impl); FIREBASE_ASSERT(g_initialized_count); @@ -324,7 +338,7 @@ JNIEXPORT void JNICALL JniAuthStateListener_nativeOnAuthStateChanged( JNIEnv* env, jobject clazz, jlong callback_data) { AuthData* auth_data = reinterpret_cast(callback_data); // Update our pointer to the Android FirebaseUser that we're wrapping. - UpdateCurrentUser(auth_data); + UpdateCurrentUser(env, auth_data); NotifyAuthStateListeners(auth_data); } @@ -333,7 +347,7 @@ JNIEXPORT void JNICALL JniIdTokenListener_nativeOnIdTokenChanged( AuthData* auth_data = reinterpret_cast(callback_data); auth_data->SetExpectIdTokenListenerCallback(false); // Update our pointer to the Android FirebaseUser that we're wrapping. - UpdateCurrentUser(auth_data); + UpdateCurrentUser(env, auth_data); NotifyIdTokenListeners(auth_data); } @@ -375,6 +389,8 @@ static void ReadProviderResult( Future Auth::FetchProvidersForEmail( const char* email) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc( kAuthFn_FetchProvidersForEmail); @@ -387,34 +403,42 @@ Future Auth::FetchProvidersForEmail( env->DeleteLocalRef(j_email); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, ReadProviderResult); + RegisterCallback(auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, ReadProviderResult); env->DeleteLocalRef(pending_result); } return MakeFuture(&futures, handle); } Future Auth::SignInWithCustomToken_DEPRECATED(const char* token) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED); - JNIEnv* env = Env(auth_data_); + SafeFutureHandle future_handle = + auth_data_->future_impl.SafeAlloc( + kAuthFn_SignInWithCustomToken_DEPRECATED); + Future future = MakeFuture(&auth_data_->future_impl, future_handle); + JNIEnv* env = Env(auth_data_); jstring j_token = env->NewStringUTF(token); jobject pending_result = env->CallObjectMethod( AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInWithCustomToken), j_token); env->DeleteLocalRef(j_token); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, + if (!CheckAndCompleteFutureOnError(env, &futures, future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, + auth_data_->future_api_id, &auth_data_->future_impl, ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } Future Auth::SignInWithCredential_DEPRECATED( const Credential& credential) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED); @@ -430,7 +454,8 @@ Future Auth::SignInWithCredential_DEPRECATED( CredentialFromImpl(credential.impl_)); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, + RegisterCallback(auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } @@ -440,54 +465,63 @@ Future Auth::SignInWithCredential_DEPRECATED( Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential& credential) { - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc( + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); + const auto future_handle = auth_data_->future_impl.SafeAlloc( kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED); JNIEnv* env = Env(auth_data_); // If the credential itself is in an error state, don't try signing in. if (credential.error_code_ != kAuthErrorNone) { - futures.Complete(handle, credential.error_code_, - credential.error_message_.c_str()); + auth_data_->future_impl.Complete(future_handle, credential.error_code_, + credential.error_message_.c_str()); } else { jobject pending_result = env->CallObjectMethod( AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInWithCredential), CredentialFromImpl(credential.impl_)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, ReadSignInResult); + if (!CheckAndCompleteFutureOnError(env, &auth_data_->future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, + auth_data_->future_api_id, &auth_data_->future_impl, + ReadSignInResult); env->DeleteLocalRef(pending_result); } } - return MakeFuture(&futures, handle); + return MakeFuture(&auth_data_->future_impl, future_handle); } Future Auth::SignInWithProvider_DEPRECATED( FederatedAuthProvider* provider) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); FIREBASE_ASSERT_RETURN(Future(), provider); + MutexLock(auth_data_->auth_mutex); return provider->SignIn(auth_data_); } Future Auth::SignInAnonymously_DEPRECATED() { - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED); + const auto handle = auth_data_->future_impl.SafeAlloc( + kAuthFn_SignInAnonymously_DEPRECATED); + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); JNIEnv* env = Env(auth_data_); - jobject pending_result = env->CallObjectMethod( AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInAnonymously)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, + if (!CheckAndCompleteFutureOnError(env, &auth_data_->future_impl, handle)) { + RegisterCallback(auth_data_, pending_result, handle, + auth_data_->future_api_id, &auth_data_->future_impl, ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return MakeFuture(&auth_data_->future_impl, handle); } Future Auth::SignInWithEmailAndPassword_DEPRECATED( const char* email, const char* password) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED); @@ -496,7 +530,7 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED( futures.Complete(handle, (!email || strlen(email) == 0) ? kAuthErrorMissingEmail : kAuthErrorMissingPassword, - kErrorEmptyEmailPassword); + kErrorEmptyEmailPasswordErrorMessage); return MakeFuture(&futures, handle); } JNIEnv* env = Env(auth_data_); @@ -511,7 +545,8 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED( env->DeleteLocalRef(j_password); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, + RegisterCallback(auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } @@ -521,16 +556,18 @@ Future Auth::SignInWithEmailAndPassword_DEPRECATED( Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( const char* email, const char* password) { - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc( + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); + const auto future_handle = auth_data_->future_impl.SafeAlloc( kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED); if (!email || strlen(email) == 0 || !password || strlen(password) == 0) { - futures.Complete(handle, - (!email || strlen(email) == 0) ? kAuthErrorMissingEmail - : kAuthErrorMissingPassword, - kErrorEmptyEmailPassword); - return MakeFuture(&futures, handle); + auth_data_->future_impl.Complete(future_handle, + (!email || strlen(email) == 0) + ? kAuthErrorMissingEmail + : kAuthErrorMissingPassword, + kErrorEmptyEmailPasswordErrorMessage); + return MakeFuture(&auth_data_->future_impl, future_handle); } JNIEnv* env = Env(auth_data_); @@ -543,34 +580,33 @@ Future Auth::CreateUserWithEmailAndPassword_DEPRECATED( env->DeleteLocalRef(j_email); env->DeleteLocalRef(j_password); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, + if (!CheckAndCompleteFutureOnError(env, &auth_data_->future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, + auth_data_->future_api_id, &auth_data_->future_impl, ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return MakeFuture(&auth_data_->future_impl, future_handle); } // It's safe to return a direct pointer to `current_user` because that class // holds nothing but a pointer to AuthData, which never changes. // All User functions that require synchronization go through AuthData's mutex. User* Auth::current_user_DEPRECATED() { - if (!auth_data_) return nullptr; - MutexLock lock(auth_data_->future_impl.mutex()); - - // auth_data_->current_user should be available after Auth is created because - // persistent is loaded during the constructor of Android FirebaseAuth. - // This may change to make FirebaseAuth.getCurrentUser() to block and wait for - // persistent loading. However, it is safe to access auth_data_->current_user - // here since FirebaseAuth.getCurrentUser() (Android) is called in - // InitPlatformAuth(). - User* user = - auth_data_->user_impl == nullptr ? nullptr : &auth_data_->current_user; - return user; + FIREBASE_ASSERT_RETURN(nullptr, auth_data_); + MutexLock lock(auth_data_->auth_mutex); + if (auth_data_->deprecated_fields.user_deprecated == nullptr || + !auth_data_->deprecated_fields.user_deprecated->is_valid()) { + return nullptr; + } else { + return auth_data_->deprecated_fields.user_deprecated; + } } std::string Auth::language_code() const { - if (!auth_data_) return std::string(); + FIREBASE_ASSERT_RETURN(std::string(), auth_data_); + MutexLock(auth_data_->auth_mutex); JNIEnv* env = Env(auth_data_); jobject j_pending_result = env->CallObjectMethod( AuthImpl(auth_data_), auth::GetMethodId(auth::kGetLanguageCode)); @@ -582,7 +618,8 @@ std::string Auth::language_code() const { } void Auth::set_language_code(const char* language_code) { - if (!auth_data_) return; + FIREBASE_ASSERT_RETURN_VOID(auth_data_); + MutexLock(auth_data_->auth_mutex); JNIEnv* env = Env(auth_data_); jstring j_language_code = nullptr; if (language_code != nullptr) { @@ -598,7 +635,7 @@ void Auth::set_language_code(const char* language_code) { } void Auth::UseAppLanguage() { - if (!auth_data_) return; + FIREBASE_ASSERT_RETURN_VOID(auth_data_); JNIEnv* env = Env(auth_data_); env->CallVoidMethod(AuthImpl(auth_data_), auth::GetMethodId(auth::kUseAppLanguage)); @@ -606,16 +643,22 @@ void Auth::UseAppLanguage() { } void Auth::SignOut() { + FIREBASE_ASSERT_RETURN_VOID(auth_data_); + MutexLock(auth_data_->auth_mutex); JNIEnv* env = Env(auth_data_); env->CallVoidMethod(AuthImpl(auth_data_), auth::GetMethodId(auth::kSignOut)); firebase::util::CheckAndClearJniExceptions(env); // Release our current user implementation in Java. MutexLock lock(auth_data_->future_impl.mutex()); - SetImplFromLocalRef(env, nullptr, &auth_data_->user_impl); + SetImplFromLocalRef(env, nullptr, + &auth_data_->deprecated_fields.android_user_impl); + SetUserImpl(env, auth_data_, nullptr); } Future Auth::SendPasswordResetEmail(const char* email) { + FIREBASE_ASSERT_RETURN(Future(), auth_data_); + MutexLock(auth_data_->auth_mutex); ReferenceCountedFutureImpl& futures = auth_data_->future_impl; const auto handle = futures.SafeAlloc(kAuthFn_SendPasswordResetEmail); @@ -631,7 +674,8 @@ Future Auth::SendPasswordResetEmail(const char* email) { env->DeleteLocalRef(j_email); if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); + RegisterCallback(auth_data_, pending_result, handle, + auth_data_->future_api_id, &futures, nullptr); env->DeleteLocalRef(pending_result); } return MakeFuture(&futures, handle); diff --git a/auth/src/android/common_android.cc b/auth/src/android/common_android.cc index f1f2587cea..f0dea43cf8 100644 --- a/auth/src/android/common_android.cc +++ b/auth/src/android/common_android.cc @@ -483,9 +483,13 @@ void ReadSignInResult(jobject result, FutureCallbackData* d, util::CheckAndClearJniExceptions(env); // Update our pointer to the Android FirebaseUser that we're wrapping. - // Note: Cannot call UpdateCurrentUser(d->auth_data) because the Java + // Note: Cannot call UpdateCurrentUser(env, d->auth_data) because the Java // Auth class has not been updated at this point. - SetImplFromLocalRef(env, j_user, &d->auth_data->user_impl); + SetImplFromLocalRef(env, j_user, + &d->auth_data->deprecated_fields.android_user_impl); + SetUserImpl(env, d->auth_data, + static_cast( + d->auth_data->deprecated_fields.android_user_impl)); // Grab the additional user info too. // Additional user info is not guaranteed to exist, so could be nullptr. @@ -519,9 +523,13 @@ void ReadUserFromSignInResult(jobject result, FutureCallbackData* d, util::CheckAndClearJniExceptions(env); // Update our pointer to the Android FirebaseUser that we're wrapping. - // Note: Cannot call UpdateCurrentUser(d->auth_data) because the Java + // Note: Cannot call UpdateCurrentUser(env, d->auth_data) because the Java // Auth class has not been updated at this point. - SetImplFromLocalRef(env, j_user, &d->auth_data->user_impl); + SetImplFromLocalRef(env, j_user, + &d->auth_data->deprecated_fields.android_user_impl); + SetUserImpl(env, d->auth_data, + static_cast( + d->auth_data->deprecated_fields.android_user_impl)); } // Return a pointer to the current user, if the current user is valid. diff --git a/auth/src/android/common_android.h b/auth/src/android/common_android.h index 6cbe4ac9c0..a54ba0d586 100644 --- a/auth/src/android/common_android.h +++ b/auth/src/android/common_android.h @@ -50,20 +50,136 @@ template struct FutureCallbackData { // During the callback, read `result` data from Java into the returned // C++ data in `d->future_data->Data()`. - typedef void ReadFutureResultFn(jobject result, FutureCallbackData* d, + typedef void ReadFutureResultFn(jobject result, + FutureCallbackData* future_callback_Data, bool success, void* void_data); - FutureCallbackData(const SafeFutureHandle& handle, AuthData* auth_data, + FutureCallbackData(AuthData* auth_data, const SafeFutureHandle& handle, + ReferenceCountedFutureImpl* future_impl, ReadFutureResultFn* future_data_read_fn) - : handle(handle), - auth_data(auth_data), + : auth_data(auth_data), + handle(handle), + future_impl(future_impl), future_data_read_fn(future_data_read_fn) {} - - SafeFutureHandle handle; AuthData* auth_data; + SafeFutureHandle handle; + ReferenceCountedFutureImpl* future_impl; ReadFutureResultFn* future_data_read_fn; }; +// Contains the interface between the public API and the underlying +// Android Java SDK FirebaseUser implemention. +class UserInternal { + public: + // Constructor + explicit UserInternal(AuthData* auth_data, jobject android_user); + + // Copy constructor. + UserInternal(const UserInternal& user_internal); + + ~UserInternal(); + + // @deprecated + // + // Provides a mechanism for the deprecated auth-contained user object to + // update its underlying Android Java SDK FirebaseUser object. Assumes that + // a global ref has already been set on android_user. Releases the global + // ref on any previously held user. + void set_native_user_object_deprecated(jobject android_user); + + bool is_valid() const; + + Future GetToken(bool force_refresh); + Future GetTokenLastResult() const; + + Future UpdateEmail(const char* email); + Future UpdateEmailLastResult() const; + + std::vector provider_data() const; + const std::vector& provider_data_DEPRECATED(); + + Future UpdatePassword(const char* password); + Future UpdatePasswordLastResult() const; + + Future UpdateUserProfile(const User::UserProfile& profile); + Future UpdateUserProfileLastResult() const; + + Future SendEmailVerification(); + Future SendEmailVerificationLastResult() const; + + Future LinkWithCredential_DEPRECATED(const Credential& credential); + Future LinkWithCredentialLastResult_DEPRECATED() const; + + Future LinkAndRetrieveDataWithCredential_DEPRECATED( + const Credential& credential); + Future LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() + const; + + Future LinkWithProvider_DEPRECATED( + FederatedAuthProvider* provider); + Future LinkWithProviderLastResult_DEPRECATED() const; + + Future Unlink_DEPRECATED(const char* provider); + Future UnlinkLastResult_DEPRECATED() const; + + Future UpdatePhoneNumberCredential_DEPRECATED( + const Credential& credential); + Future UpdatePhoneNumberCredentialLastResult_DEPRECATED() const; + + Future Reload(); + Future ReloadLastResult() const; + + Future Reauthenticate(const Credential& credential); + Future ReauthenticateLastResult() const; + + Future ReauthenticateAndRetrieveData_DEPRECATED( + const Credential& credential); + Future ReauthenticateAndRetrieveDataLastResult_DEPRECATED() + const; + + Future ReauthenticateWithProvider_DEPRECATED( + FederatedAuthProvider* provider); + Future ReauthenticateWithProviderLastResult_DEPRECATED() const; + + Future Delete(); + Future DeleteLastResult() const; + + UserMetadata metadata() const; + bool is_email_verified() const; + bool is_anonymous() const; + std::string uid() const; + std::string email() const; + std::string display_name() const; + std::string phone_number() const; + std::string photo_url() const; + std::string provider_id() const; + + private: + friend class firebase::auth::FederatedOAuthProvider; + friend class firebase::auth::User; + + void clear_user_infos(); + + // Pointer to the originating auth context. + AuthData* auth_data_; + + // Android Java SDK Implementation of a FirebaseUser object. + jobject user_; + + // Future data used to synchronize asynchronous calls. + FutureData future_data_; + + // Used to support older method invocation of provider_data_DEPRECATED(). + std::vector user_infos_; + + // Guard against changes to the user_ object. + Mutex user_mutex_; + + // Used to identify on-going futures in case we need to cancel them + // upon UserInternal destruction. + std::string future_api_id_; +}; + // The `ReadFutureResultFn` for `SignIn` APIs. // Reads the `AuthResult` in `result` and initialize the `User*` in `void_data`. void ReadSignInResult(jobject result, FutureCallbackData* d, @@ -112,18 +228,28 @@ inline JNIEnv* Env(AuthData* auth_data) { return auth_data->app->GetJNIEnv(); } // Delete the existing impl pointer global reference, if it already exists. void SetImplFromLocalRef(JNIEnv* env, jobject j_local, void** impl); +// Synchronize the current user. +void UpdateCurrentUser(JNIEnv* env, AuthData* auth_data); + +/// @deprecated +/// +/// Replace the platform-dependent FirebaseUser Android SDK object. +/// Note: this function is only used to support DEPRECATED methods which return +/// User*. This functionality should be removed when those deprecated methods +/// are removed. +inline void SetUserImpl(JNIEnv* env, AuthData* _Nonnull auth_data, + jobject j_user) { + assert(auth_data->deprecated_fields.user_internal_deprecated); + auth_data->deprecated_fields.user_internal_deprecated + ->set_native_user_object_deprecated(j_user); +} + // Return the Java FirebaseAuth class from our platform-independent // representation. inline jobject AuthImpl(AuthData* auth_data) { return static_cast(auth_data->auth_impl); } -// Return the Java FirebaseUser class from our platform-independent -// representation. -inline jobject UserImpl(AuthData* auth_data) { - return static_cast(auth_data->user_impl); -} - // Return a platform-independent representation of Java's FirebaseUser class. inline void* ImplFromUser(jobject user) { return static_cast(user); } @@ -177,24 +303,25 @@ AuthError MapFutureCallbackResultToAuthError(JNIEnv* env, jobject result, template void FutureCallback(JNIEnv* env, jobject result, util::FutureResult result_code, const char* status_message, void* callback_data) { - FutureCallbackData* data = + FutureCallbackData* future_callback_data = static_cast*>(callback_data); bool success = false; const AuthError error = MapFutureCallbackResultToAuthError(env, result, result_code, &success); // Finish off the asynchronous call so that the caller can read it. - data->auth_data->future_impl.Complete( - data->handle, error, status_message, - [result, success, data](void* user_data) { - if (data->future_data_read_fn != nullptr) { - data->future_data_read_fn(result, data, success, user_data); + future_callback_data->future_impl->Complete( + future_callback_data->handle, error, status_message, + [result, success, future_callback_data](void* user_data) { + if (future_callback_data->future_data_read_fn != nullptr) { + future_callback_data->future_data_read_fn( + result, future_callback_data, success, user_data); } }); // Remove the callback structure that was allocated when the callback was // created in SetupFuture(). - delete data; - data = nullptr; + delete future_callback_data; + future_callback_data = nullptr; } // The function called by the Java thread when a result completes. @@ -203,7 +330,7 @@ void FederatedAuthProviderFutureCallback(JNIEnv* env, jobject result, util::FutureResult result_code, const char* status_message, void* callback_data) { - FutureCallbackData* data = + FutureCallbackData* future_callback_data = static_cast*>(callback_data); bool success = false; AuthError error = @@ -215,18 +342,19 @@ void FederatedAuthProviderFutureCallback(JNIEnv* env, jobject result, error = kAuthErrorInvalidProviderId; } // Finish off the asynchronous call so that the caller can read it. - data->auth_data->future_impl.Complete( - data->handle, error, status_message, - [result, success, data](void* user_data) { - if (data->future_data_read_fn != nullptr) { - data->future_data_read_fn(result, data, success, user_data); + future_callback_data->future_impl->Complete( + future_callback_data->handle, error, status_message, + [result, success, future_callback_data](void* user_data) { + if (future_callback_data->future_data_read_fn != nullptr) { + future_callback_data->future_data_read_fn( + result, future_callback_data, success, user_data); } }); // Remove the callback structure that was allocated when the callback was // created in SetupFuture(). - delete data; - data = nullptr; + delete future_callback_data; + future_callback_data = nullptr; } // Ensure `FutureCallback` gets called when `pending_result` completes. @@ -234,13 +362,14 @@ void FederatedAuthProviderFutureCallback(JNIEnv* env, jobject result, // data from Java, and then complete the Future for `handle`. template void RegisterCallback( - jobject pending_result, SafeFutureHandle handle, AuthData* auth_data, + AuthData* auth_data, jobject pending_result, SafeFutureHandle handle, + const std::string& future_api_id, ReferenceCountedFutureImpl* future_impl, typename FutureCallbackData::ReadFutureResultFn read_result_fn) { // The FutureCallbackData structure is deleted in FutureCallback(). util::RegisterCallbackOnTask( Env(auth_data), pending_result, FutureCallback, - new FutureCallbackData(handle, auth_data, read_result_fn), - auth_data->future_api_id.c_str()); + new FutureCallbackData(auth_data, handle, future_impl, read_result_fn), + future_api_id.c_str()); } // Akin to RegisterCallback above, but has a special callback handler @@ -250,14 +379,15 @@ void RegisterCallback( // with the existing API behavior for other sign in events. template void RegisterFederatedAuthProviderCallback( - jobject pending_result, SafeFutureHandle handle, AuthData* auth_data, + AuthData* auth_data, jobject pending_result, SafeFutureHandle handle, + const std::string& future_api_id, ReferenceCountedFutureImpl* future_impl, typename FutureCallbackData::ReadFutureResultFn read_result_fn) { // The FutureCallbackData structure is deleted in // FederatedAuthProviderFutureCallback(). util::RegisterCallbackOnTask( Env(auth_data), pending_result, FederatedAuthProviderFutureCallback, - new FutureCallbackData(handle, auth_data, read_result_fn), - auth_data->future_api_id.c_str()); + new FutureCallbackData(auth_data, handle, future_impl, read_result_fn), + future_api_id.c_str()); } // Checks if there was an error, and if so, completes the given future with the diff --git a/auth/src/android/credential_android.cc b/auth/src/android/credential_android.cc index e9512f9bf6..1c06f266b7 100644 --- a/auth/src/android/credential_android.cc +++ b/auth/src/android/credential_android.cc @@ -652,24 +652,24 @@ Future GameCenterAuthProvider::GetCredential() { // Game Center is not available on Android bool is_gamecenter_available_on_android = false; - auto future_api = GetCredentialFutureImpl(); - const auto handle = - future_api->SafeAlloc(kCredentialFn_GameCenterGetCredential); + ReferenceCountedFutureImpl* future_impl = GetCredentialFutureImpl(); + const auto future_handle = + future_impl->SafeAlloc(kCredentialFn_GameCenterGetCredential); - future_api->Complete(handle, kAuthErrorInvalidCredential, - "GameCenter is not supported on Android."); + future_impl->Complete(future_handle, kAuthErrorInvalidCredential, + "GameCenter is not supported on Android."); - FIREBASE_ASSERT_RETURN(MakeFuture(future_api, handle), + FIREBASE_ASSERT_RETURN(MakeFuture(future_impl, future_handle), is_gamecenter_available_on_android); - return MakeFuture(future_api, handle); + return MakeFuture(future_impl, future_handle); } // static Future GameCenterAuthProvider::GetCredentialLastResult() { - auto future_api = GetCredentialFutureImpl(); + ReferenceCountedFutureImpl* future_impl = GetCredentialFutureImpl(); auto last_result = - future_api->LastResult(kCredentialFn_GameCenterGetCredential); + future_impl->LastResult(kCredentialFn_GameCenterGetCredential); return static_cast&>(last_result); } @@ -1013,75 +1013,80 @@ Future FederatedOAuthProvider::SignIn(AuthData* auth_data) { assert(auth_data); JNIEnv* env = Env(auth_data); - ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = futures.SafeAlloc( + ReferenceCountedFutureImpl& future_impl = auth_data->future_impl; + const auto future_handle = future_impl.SafeAlloc( kAuthFn_SignInWithProvider_DEPRECATED, SignInResult()); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { jobject task = env->CallObjectMethod( AuthImpl(auth_data), auth_idp::GetMethodId(auth_idp::kStartActivityForSignInWithProvider), auth_data->app->activity(), oauthprovider); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterFederatedAuthProviderCallback(task, handle, auth_data, - ReadSignInResult); + + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { + RegisterFederatedAuthProviderCallback( + auth_data, task, future_handle, auth_data->future_api_id, + &auth_data->future_impl, ReadSignInResult); } env->DeleteLocalRef(task); } env->DeleteLocalRef(oauthprovider); - return MakeFuture(&futures, handle); + return MakeFuture(&future_impl, future_handle); } -Future FederatedOAuthProvider::Link(AuthData* auth_data) { - assert(auth_data); - JNIEnv* env = Env(auth_data); - ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = futures.SafeAlloc( +Future FederatedOAuthProvider::Link(AuthData* auth_data, + UserInternal* user_internal) { + ReferenceCountedFutureImpl& future_impl = + user_internal->future_data_.future_impl; + const auto future_handle = future_impl.SafeAlloc( kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + JNIEnv* env = Env(auth_data); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { jobject task = env->CallObjectMethod( - UserImpl(auth_data), + user_internal->user_, user_idp::GetMethodId(user_idp::kStartActivityForLinkWithProvider), auth_data->app->activity(), oauthprovider); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterFederatedAuthProviderCallback(task, handle, auth_data, - ReadSignInResult); + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { + RegisterFederatedAuthProviderCallback( + auth_data, task, future_handle, auth_data->future_api_id, + &auth_data->future_impl, ReadSignInResult); } env->DeleteLocalRef(task); } env->DeleteLocalRef(oauthprovider); - return MakeFuture(&futures, handle); + return MakeFuture(&future_impl, future_handle); } Future FederatedOAuthProvider::Reauthenticate( - AuthData* auth_data) { - assert(auth_data); - JNIEnv* env = Env(auth_data); - ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = futures.SafeAlloc( + AuthData* auth_data, UserInternal* user_internal) { + ReferenceCountedFutureImpl& future_impl = + user_internal->future_data_.future_impl; + const auto future_handle = future_impl.SafeAlloc( kUserFn_ReauthenticateWithProvider_DEPRECATED, SignInResult()); + JNIEnv* env = Env(auth_data); jobject oauthprovider = ConstructOAuthProvider(auth_data, provider_data_); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { jobject task = env->CallObjectMethod( - UserImpl(auth_data), + user_internal->user_, user_idp::GetMethodId( user_idp::kStartActivityForReauthenticateWithProvider), auth_data->app->activity(), oauthprovider); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterFederatedAuthProviderCallback(task, handle, auth_data, - ReadSignInResult); + if (!CheckAndCompleteFutureOnError(env, &future_impl, future_handle)) { + RegisterFederatedAuthProviderCallback( + auth_data, task, future_handle, auth_data->future_api_id, + &auth_data->future_impl, ReadSignInResult); } env->DeleteLocalRef(task); } env->DeleteLocalRef(oauthprovider); - return MakeFuture(&futures, handle); + return MakeFuture(&future_impl, future_handle); } } // namespace auth diff --git a/auth/src/android/user_android.cc b/auth/src/android/user_android.cc index 2df7db018e..9dfc927f03 100644 --- a/auth/src/android/user_android.cc +++ b/auth/src/android/user_android.cc @@ -128,7 +128,7 @@ METHOD_LOOKUP_DEFINITION( "com/google/firebase/auth/UserProfileChangeRequest$Builder", USER_PROFILE_BUILDER_METHODS) -bool CacheUserMethodIds(JNIEnv* env, jobject activity) { +bool CacheUserMethodIds(JNIEnv *env, jobject activity) { return phonecredential::CacheMethodIds(env, activity) && tokenresult::CacheMethodIds(env, activity) && user::CacheMethodIds(env, activity) && @@ -137,7 +137,7 @@ bool CacheUserMethodIds(JNIEnv* env, jobject activity) { userprofilebuilder::CacheMethodIds(env, activity); } -void ReleaseUserClasses(JNIEnv* env) { +void ReleaseUserClasses(JNIEnv *env) { phonecredential::ReleaseClass(env); tokenresult::ReleaseClass(env); user::ReleaseClass(env); @@ -146,137 +146,407 @@ void ReleaseUserClasses(JNIEnv* env) { userprofilebuilder::ReleaseClass(env); } +/// +/// AndroidWrappedUserInfo Class. +/// Queries data out of Java Android SDK UserInfo objects. +/// enum PropertyType { kPropertyTypeString, kPropertyTypeUri }; -static std::string GetUserProperty(AuthData* auth_data, jobject impl, - userinfo::Method method_id, - PropertyType type = kPropertyTypeString) { - JNIEnv* env = Env(auth_data); - jobject property = - impl ? env->CallObjectMethod(impl, userinfo::GetMethodId(method_id)) - : nullptr; - if (firebase::util::CheckAndClearJniExceptions(env) || !property) { - return std::string(); +class AndroidWrappedUserInfo : public UserInfoInterface { + public: + AndroidWrappedUserInfo(AuthData *auth_data, jobject user_info) + : auth_data_(auth_data), user_info_(user_info) { + // Convert `user_info` to a global reference. + JNIEnv *env = Env(auth_data_); + user_info_ = env->NewGlobalRef(user_info); + env->DeleteLocalRef(user_info); } - if (type == kPropertyTypeUri) { - return JniUriToString(env, property); + + virtual ~AndroidWrappedUserInfo() { + // Delete global reference. + JNIEnv *env = Env(auth_data_); + env->DeleteGlobalRef(user_info_); + user_info_ = nullptr; + auth_data_ = nullptr; + } + + std::string uid() const override { + return GetUserProperty(userinfo::kGetUid); + } + + std::string email() const override { + return GetUserProperty(userinfo::kGetEmail); + } + + std::string display_name() const override { + return GetUserProperty(userinfo::kGetDisplayName); + } + + std::string phone_number() const override { + return GetUserProperty(userinfo::kGetPhoneNumber); + } + + std::string photo_url() const override { + return GetUserProperty(userinfo::kGetPhotoUrl, kPropertyTypeUri); + } + + std::string provider_id() const override { + return GetUserProperty(userinfo::kGetProviderId); + } + + private: + std::string GetUserProperty(userinfo::Method method_id, + PropertyType type = kPropertyTypeString) const { + JNIEnv *env = Env(auth_data_); + jobject property = user_info_ + ? env->CallObjectMethod( + user_info_, userinfo::GetMethodId(method_id)) + : nullptr; + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { + return std::string(); + } + if (type == kPropertyTypeUri) { + return JniUriToString(env, property); + } else { + // type == kPropertyTypeString + return JniStringToString(env, property); + } + } + + /// The AuthData context, required JNI environment data. + AuthData *auth_data_; + + /// Pointer to the main class. + /// Needed for context in implementation of virtuals. + jobject user_info_; +}; + +/// +/// User Class +/// Platform specific implementation of UserInternal. +/// +User::User(AuthData *auth_data, UserInternal *user_internal) { + assert(auth_data); + auth_data_ = auth_data; + if (user_internal == nullptr) { + // Create an invalid user internal. + // This will return is_valid() false, and operations will fail. + user_internal_ = new UserInternal(auth_data_, nullptr); + } else { + user_internal_ = user_internal; + } +} + +User::User(const User &user) { + assert(user.auth_data_); + auth_data_ = user.auth_data_; + if (user.user_internal_ != nullptr) { + user_internal_ = new UserInternal(auth_data_, user.user_internal_->user_); + } else { + user_internal_ = new UserInternal(auth_data_, nullptr); + } +} + +User::~User() { + delete user_internal_; + user_internal_ = nullptr; + auth_data_ = nullptr; +} + +User &User::operator=(const User &user) { + assert(user_internal_); + delete user_internal_; + + auth_data_ = user.auth_data_; + + if (user.user_internal_ != nullptr) { + user_internal_ = new UserInternal(auth_data_, user.user_internal_->user_); } else { - // type == kPropertyTypeString - return JniStringToString(env, property); + user_internal_ = new UserInternal(auth_data_, nullptr); } + + return *this; } -static std::string GetUID(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetUid); +bool User::is_valid() const { + assert(user_internal_); + return user_internal_->is_valid(); } -static std::string GetEmail(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetEmail); +Future User::GetToken(bool force_refresh) { + assert(user_internal_); + return user_internal_->GetToken(force_refresh); +} + +std::vector User::provider_data() const { + assert(user_internal_); + return user_internal_->provider_data(); } -static std::string GetDisplayName(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetDisplayName); +const std::vector &User::provider_data_DEPRECATED() { + assert(user_internal_); + return user_internal_->provider_data_DEPRECATED(); } -static std::string GetPhoneNumber(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetPhoneNumber); +Future User::UpdateEmail(const char *email) { + assert(user_internal_); + return user_internal_->UpdateEmail(email); } -static std::string GetPhotoUrl(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetPhotoUrl, - kPropertyTypeUri); +Future User::UpdateEmailLastResult() const { + assert(user_internal_); + return user_internal_->UpdateEmailLastResult(); } -static std::string GetProviderId(AuthData* auth_data, jobject impl) { - return GetUserProperty(auth_data, impl, userinfo::kGetProviderId); +Future User::UpdatePassword(const char *password) { + assert(user_internal_); + return user_internal_->UpdatePassword(password); } -User::~User() {} +Future User::UpdatePasswordLastResult() const { + assert(user_internal_); + return user_internal_->UpdatePasswordLastResult(); +} + +Future User::Reauthenticate(const Credential &credential) { + assert(user_internal_); + return user_internal_->Reauthenticate(credential); +} + +Future User::ReauthenticateLastResult() const { + assert(user_internal_); + return user_internal_->ReauthenticateLastResult(); +} + +Future User::ReauthenticateAndRetrieveData_DEPRECATED( + const Credential &credential) { + assert(user_internal_); + return user_internal_->ReauthenticateAndRetrieveData_DEPRECATED(credential); +} + +Future User::ReauthenticateAndRetrieveDataLastResult_DEPRECATED() + const { + assert(user_internal_); + return user_internal_->ReauthenticateAndRetrieveDataLastResult_DEPRECATED(); +} + +Future User::ReauthenticateWithProvider_DEPRECATED( + FederatedAuthProvider *provider) const { + assert(user_internal_); + return user_internal_->ReauthenticateWithProvider_DEPRECATED(provider); +} + +Future User::SendEmailVerification() { + assert(user_internal_); + return user_internal_->SendEmailVerification(); +} + +Future User::SendEmailVerificationLastResult() const { + assert(user_internal_); + return user_internal_->SendEmailVerificationLastResult(); +} + +Future User::UpdateUserProfile(const UserProfile &profile) { + assert(user_internal_); + return user_internal_->UpdateUserProfile(profile); +} + +Future User::UpdateUserProfileLastResult() const { + assert(user_internal_); + return user_internal_->UpdateUserProfileLastResult(); +} + +Future User::LinkWithCredential_DEPRECATED( + const Credential &credential) { + assert(user_internal_); + return user_internal_->LinkWithCredential_DEPRECATED(credential); +} + +Future User::LinkWithCredentialLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_->LinkWithCredentialLastResult_DEPRECATED(); +} + +Future User::LinkAndRetrieveDataWithCredential_DEPRECATED( + const Credential &credential) { + assert(user_internal_); + return user_internal_->LinkAndRetrieveDataWithCredential_DEPRECATED( + credential); +} + +Future +User::LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_ + ->LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED(); +} + +Future User::LinkWithProvider_DEPRECATED( + FederatedAuthProvider *provider) { + assert(user_internal_); + return user_internal_->LinkWithProvider_DEPRECATED(provider); +} + +Future User::Unlink_DEPRECATED(const char *provider) { + assert(user_internal_); + return user_internal_->Unlink_DEPRECATED(provider); +} + +Future User::UnlinkLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_->UnlinkLastResult_DEPRECATED(); +} + +Future User::UpdatePhoneNumberCredential_DEPRECATED( + const Credential &credential) { + assert(user_internal_); + return user_internal_->UpdatePhoneNumberCredential_DEPRECATED(credential); +} + +Future User::UpdatePhoneNumberCredentialLastResult_DEPRECATED() const { + assert(user_internal_); + return user_internal_->UpdatePhoneNumberCredentialLastResult_DEPRECATED(); +} + +Future User::Reload() { + assert(user_internal_); + return user_internal_->Reload(); +} + +Future User::ReloadLastResult() const { + assert(user_internal_); + return user_internal_->ReloadLastResult(); +} + +Future User::Delete() { + assert(user_internal_); + return user_internal_->Delete(); +} + +Future User::DeleteLastResult() const { + assert(user_internal_); + return user_internal_->DeleteLastResult(); +} + +UserMetadata User::metadata() const { + assert(user_internal_); + return user_internal_->metadata(); +} + +bool User::is_email_verified() const { + assert(user_internal_); + return user_internal_->is_email_verified(); +} + +bool User::is_anonymous() const { + assert(user_internal_); + return user_internal_->is_anonymous(); +} std::string User::uid() const { - return ValidUser(auth_data_) ? GetUID(auth_data_, UserImpl(auth_data_)) : ""; + assert(user_internal_); + return user_internal_->uid(); } std::string User::email() const { - return ValidUser(auth_data_) ? GetEmail(auth_data_, UserImpl(auth_data_)) - : ""; + assert(user_internal_); + return user_internal_->email(); } std::string User::display_name() const { - return ValidUser(auth_data_) - ? GetDisplayName(auth_data_, UserImpl(auth_data_)) - : ""; -} - -std::string User::phone_number() const { - return ValidUser(auth_data_) - ? GetPhoneNumber(auth_data_, UserImpl(auth_data_)) - : ""; + assert(user_internal_); + return user_internal_->display_name(); } std::string User::photo_url() const { - return ValidUser(auth_data_) ? GetPhotoUrl(auth_data_, UserImpl(auth_data_)) - : ""; + assert(user_internal_); + return user_internal_->photo_url(); } std::string User::provider_id() const { - return ValidUser(auth_data_) ? GetProviderId(auth_data_, UserImpl(auth_data_)) - : ""; + assert(user_internal_); + return user_internal_->provider_id(); } -class AndroidWrappedUserInfo : public UserInfoInterface { - public: - AndroidWrappedUserInfo(AuthData* auth_data, jobject user_info) - : auth_data_(auth_data), user_info_(user_info) { - // Convert `user_info` to a global reference. - JNIEnv* env = Env(auth_data_); - user_info_ = env->NewGlobalRef(user_info); - env->DeleteLocalRef(user_info); - } - - virtual ~AndroidWrappedUserInfo() { - // Delete global reference. - JNIEnv* env = Env(auth_data_); - env->DeleteGlobalRef(user_info_); - user_info_ = nullptr; - } +std::string User::phone_number() const { + assert(user_internal_); + return user_internal_->phone_number(); +} - std::string uid() const override { return GetUID(auth_data_, user_info_); } +/// +/// UserInternal Class +/// +void assign_future_id(UserInternal *user_internal, std::string *future_api_id) { + static const char *kApiIdentifier = "UserInternal"; + future_api_id->reserve(strlen(kApiIdentifier) + + 16 /* hex characters in the pointer */ + + 1 /* null terminator */); + snprintf(&((*future_api_id)[0]), future_api_id->capacity(), "%s0x%016llx", + kApiIdentifier, + static_cast( // NOLINT + reinterpret_cast(user_internal))); +} - std::string email() const override { - return GetEmail(auth_data_, user_info_); +UserInternal::UserInternal(AuthData *auth_data, jobject user) + : auth_data_(auth_data), user_(nullptr), future_data_(kUserFnCount) { + assert(auth_data_); + JNIEnv *env = Env(auth_data_); + if (user != nullptr) { + user_ = env->NewGlobalRef(user); + assert(env->ExceptionCheck() == false); } + assign_future_id(this, &future_api_id_); +} - std::string display_name() const override { - return GetDisplayName(auth_data_, user_info_); +UserInternal::UserInternal(const UserInternal &user_internal) + : auth_data_(user_internal.auth_data_), + user_(nullptr), + future_data_(kUserFnCount) { + assert(auth_data_); + JNIEnv *env = Env(auth_data_); + if (user_internal.user_ != nullptr) { + user_ = env->NewGlobalRef(user_internal.user_); + assert(env->ExceptionCheck() == false); } + assign_future_id(this, &future_api_id_); +} - std::string phone_number() const override { - return GetPhoneNumber(auth_data_, user_info_); - } +UserInternal::~UserInternal() { + MutexLock user_lock(user_mutex_); + JNIEnv *env = Env(auth_data_); + util::CancelCallbacks(env, future_api_id_.c_str()); - std::string photo_url() const override { - return GetPhotoUrl(auth_data_, user_info_); + // Make sure we don't have any pending futures in flight before we disappear. + while (!future_data_.future_impl.IsSafeToDelete()) { + internal::Sleep(100); } - std::string provider_id() const override { - return GetProviderId(auth_data_, user_info_); - } + env->DeleteGlobalRef(user_); + user_ = nullptr; + auth_data_ = nullptr; - private: - /// Pointer to the main class. - /// Needed for context in implementation of virtuals. - AuthData* auth_data_; + clear_user_infos(); +} - /// Pointer to the main class. - /// Needed for context in implementation of virtuals. - jobject user_info_; -}; +void UserInternal::set_native_user_object_deprecated(jobject user) { + MutexLock user_lock(user_mutex_); + user_ = user; +} -void ReadTokenResult(jobject result, FutureCallbackData* d, - bool success, void* void_data) { - auto data = static_cast(void_data); - JNIEnv* env = Env(d->auth_data); +bool UserInternal::is_valid() const { return user_ != nullptr; } + +void UserInternal::clear_user_infos() { + for (size_t i = 0; i < user_infos_.size(); ++i) { + delete user_infos_[i]; + user_infos_[i] = nullptr; + } + user_infos_.clear(); +} + +void ReadTokenResult(jobject result, FutureCallbackData *d, + bool success, void *void_data) { + auto data = static_cast(void_data); + JNIEnv *env = Env(d->auth_data); // `result` is of type GetTokenResult when `success` is true. if (success) { @@ -295,45 +565,82 @@ void ReadTokenResult(jobject result, FutureCallbackData* d, } } -Future User::GetToken(bool force_refresh) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::GetToken(bool force_refresh) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_GetToken, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, + &future_data_, ""); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_GetToken); - JNIEnv* env = Env(auth_data_); + + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_GetToken); + Future future = + MakeFuture(&future_data_.future_impl, future_handle); auth_data_->SetExpectIdTokenListenerCallback(force_refresh); + + JNIEnv *env = Env(auth_data_); jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kToken), force_refresh); + user_, user::GetMethodId(user::kToken), force_refresh); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, ReadTokenResult); + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadTokenResult); env->DeleteLocalRef(pending_result); } else { // If the method failed for some reason, clear the expected callback. auth_data_->SetExpectIdTokenListenerCallback(false); } - return MakeFuture(&futures, handle); + return future; } -const std::vector& User::provider_data() const { - ClearUserInfos(auth_data_); +std::vector UserInternal::provider_data() const { + JNIEnv *env = Env(auth_data_); + std::vector local_user_infos; + if (is_valid()) { + const jobject list = + env->CallObjectMethod(user_, user::GetMethodId(user::kProviderData)); + assert(env->ExceptionCheck() == false); - if (ValidUser(auth_data_)) { - JNIEnv* env = Env(auth_data_); + if (list != nullptr) { + const int num_providers = + env->CallIntMethod(list, util::list::GetMethodId(util::list::kSize)); + assert(env->ExceptionCheck() == false); + local_user_infos.resize(num_providers); + for (int i = 0; i < num_providers; ++i) { + // user_info is converted to a global reference in + // AndroidWrappedUserInfo() and the local reference is released. + jobject user_info = env->CallObjectMethod( + list, util::list::GetMethodId(util::list::kGet), i); + assert(env->ExceptionCheck() == false); + local_user_infos[i] = AndroidWrappedUserInfo(auth_data_, user_info); + } + env->DeleteLocalRef(list); + } + } + return local_user_infos; +} + +const std::vector + &UserInternal::provider_data_DEPRECATED() { + MutexLock user_info_lock(user_mutex_); + clear_user_infos(); + if (is_valid()) { + JNIEnv *env = Env(auth_data_); // getProviderData returns `List` - const jobject list = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kProviderData)); + const jobject list = + env->CallObjectMethod(user_, user::GetMethodId(user::kProviderData)); assert(env->ExceptionCheck() == false); - // Copy the list into auth_data_->user_infos. + // Copy the list into user_infos_. if (list != nullptr) { const int num_providers = env->CallIntMethod(list, util::list::GetMethodId(util::list::kSize)); assert(env->ExceptionCheck() == false); - auth_data_->user_infos.resize(num_providers); + user_infos_.resize(num_providers); for (int i = 0; i < num_providers; ++i) { // user_info is converted to a global reference in @@ -341,73 +648,97 @@ const std::vector& User::provider_data() const { jobject user_info = env->CallObjectMethod( list, util::list::GetMethodId(util::list::kGet), i); assert(env->ExceptionCheck() == false); - auth_data_->user_infos[i] = - new AndroidWrappedUserInfo(auth_data_, user_info); + user_infos_[i] = new AndroidWrappedUserInfo(auth_data_, user_info); } env->DeleteLocalRef(list); } } - // Return a reference to our internally-backed values. - return auth_data_->user_infos; + return user_infos_; } -Future User::UpdateEmail(const char* email) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdateEmail(const char *email) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_UpdateEmail, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, + &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdateEmail); - JNIEnv* env = Env(auth_data_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_UpdateEmail); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + JNIEnv *env = Env(auth_data_); jstring j_email = env->NewStringUTF(email); jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kUpdateEmail), j_email); + user_, user::GetMethodId(user::kUpdateEmail), j_email); env->DeleteLocalRef(j_email); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; +} + +Future UserInternal::UpdateEmailLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_UpdateEmail)); } -Future User::UpdatePassword(const char* password) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdatePassword(const char *password) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture( + kUserFn_UpdatePassword, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdatePassword); - JNIEnv* env = Env(auth_data_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_UpdatePassword); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + JNIEnv *env = Env(auth_data_); jstring j_password = env->NewStringUTF(password); jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kUpdatePassword), - j_password); + user_, user::GetMethodId(user::kUpdatePassword), j_password); env->DeleteLocalRef(j_password); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; +} + +Future UserInternal::UpdatePasswordLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_UpdatePassword)); } -Future User::UpdateUserProfile(const UserProfile& profile) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdateUserProfile(const User::UserProfile &profile) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture( + kUserFn_UpdateUserProfile, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_UpdateUserProfile); - JNIEnv* env = Env(auth_data_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_UpdateUserProfile); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + JNIEnv *env = Env(auth_data_); AuthError error = kAuthErrorNone; std::string exception_error_message; jobject j_user_profile_builder = env->NewObject( userprofilebuilder::GetClass(), userprofilebuilder::GetMethodId(userprofilebuilder::kConstructor)); - // Painfully call UserProfileChangeRequest.Builder.setDisplayName. + // Call UserProfileChangeRequest.Builder.setDisplayName. if (profile.display_name != nullptr) { jstring j_display_name = env->NewStringUTF(profile.display_name); jobject j_builder_discard = env->CallObjectMethod( @@ -422,7 +753,7 @@ Future User::UpdateUserProfile(const UserProfile& profile) { env->DeleteLocalRef(j_display_name); } - // Extra painfully call UserProfileChangeRequest.Builder.setPhotoUri. + // Call UserProfileChangeRequest.Builder.setPhotoUri. if (error == kAuthErrorNone && profile.photo_url != nullptr) { jobject j_uri = CharsToJniUri(env, profile.photo_url); jobject j_builder_discard = env->CallObjectMethod( @@ -448,272 +779,489 @@ Future User::UpdateUserProfile(const UserProfile& profile) { if (error == kAuthErrorNone) { // Call FirebaseUser.updateProfile. jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kUpdateUserProfile), + user_, user::GetMethodId(user::kUpdateUserProfile), j_user_profile_request); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, + future_api_id_, &future_data_.future_impl, nullptr); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } else { - futures.Complete(handle, error, exception_error_message.c_str()); + future_data_.future_impl.Complete(future_handle, error, + exception_error_message.c_str()); } if (j_user_profile_request) { env->DeleteLocalRef(j_user_profile_request); } env->DeleteLocalRef(j_user_profile_builder); - return MakeFuture(&futures, handle); + return future; } -Future User::LinkWithCredential_DEPRECATED( - const Credential& credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdateUserProfileLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_UpdateUserProfile)); +} + +Future UserInternal::SendEmailVerification() { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture( + kUserFn_SendEmailVerification, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kUserFn_LinkWithCredential_DEPRECATED); - JNIEnv* env = Env(auth_data_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_SendEmailVerification); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + JNIEnv *env = Env(auth_data_); jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kLinkWithCredential), - CredentialFromImpl(credential.impl_)); + user_, user::GetMethodId(user::kSendEmailVerification)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - ReadUserFromSignInResult); + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -Future User::LinkAndRetrieveDataWithCredential( - const Credential& credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::SendEmailVerificationLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_SendEmailVerification)); +} + +Future UserInternal::LinkWithCredential_DEPRECATED( + const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_LinkWithCredential_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, (User *)nullptr); + return future; } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc( - kUserFn_LinkAndRetrieveDataWithCredential); - JNIEnv* env = Env(auth_data_); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kLinkWithCredential), - CredentialFromImpl(credential.impl_)); + JNIEnv *env = Env(auth_data_); + jobject pending_result = + env->CallObjectMethod(user_, user::GetMethodId(user::kLinkWithCredential), + CredentialFromImpl(credential.impl_)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, ReadSignInResult); + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -Future User::LinkWithProvider_DEPRECATED( - FederatedAuthProvider* provider) const { - FIREBASE_ASSERT_RETURN(Future(), provider); - return provider->Link(auth_data_); +Future UserInternal::LinkWithCredentialLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult( + kUserFn_LinkWithCredential_DEPRECATED)); } -Future User::Unlink_DEPRECATED(const char* provider) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::LinkAndRetrieveDataWithCredential_DEPRECATED( + const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED); + Future future = + MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, SignInResult()); + return future; } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Unlink_DEPRECATED); - JNIEnv* env = Env(auth_data_); + JNIEnv *env = Env(auth_data_); + jobject pending_result = + env->CallObjectMethod(user_, user::GetMethodId(user::kLinkWithCredential), + CredentialFromImpl(credential.impl_)); + + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadSignInResult); + env->DeleteLocalRef(pending_result); + } + return future; +} + +Future +UserInternal::LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult( + kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED)); +} + +Future UserInternal::LinkWithProvider_DEPRECATED( + FederatedAuthProvider *provider) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid() || provider == nullptr) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_LinkWithProvider_DEPRECATED); + Future future = + MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, SignInResult()); + } else { + CompleteFuture(kAuthErrorInvalidParameter, + kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } + return future; + } + return provider->Link(auth_data_, this); +} + +Future UserInternal::Unlink_DEPRECATED(const char *provider) { + MutexLock user_info_lock(user_mutex_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_Unlink_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, (User *)nullptr); + return future; + } + + JNIEnv *env = Env(auth_data_); jstring j_provider = env->NewStringUTF(provider); jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kUnlink), j_provider); + user_, user::GetMethodId(user::kUnlink), j_provider); env->DeleteLocalRef(j_provider); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - ReadUserFromSignInResult); + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; +} + +Future UserInternal::UnlinkLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_Unlink_DEPRECATED)); } -Future User::UpdatePhoneNumberCredential_DEPRECATED( - const Credential& credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdatePhoneNumberCredential_DEPRECATED( + const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_UpdatePhoneNumberCredential_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, (User *)nullptr); + return future; } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kUserFn_UpdatePhoneNumberCredential_DEPRECATED); - JNIEnv* env = Env(auth_data_); + JNIEnv *env = Env(auth_data_); jobject j_credential = CredentialFromImpl(credential.impl_); if (env->IsInstanceOf(j_credential, phonecredential::GetClass())) { jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), - user::GetMethodId(user::kUpdatePhoneNumberCredential), j_credential); + user_, user::GetMethodId(user::kUpdatePhoneNumberCredential), + j_credential); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, + future_api_id_, &future_data_.future_impl, ReadUserFromSignInResult); env->DeleteLocalRef(pending_result); } } else { - futures.Complete(handle, kAuthErrorInvalidCredential, - "Credential is not a phone credential."); + CompleteFuture(kAuthErrorInvalidCredential, kInvalidCredentialErrorMessage, + future_handle, &future_data_, (User *)nullptr); } - return MakeFuture(&futures, handle); + return future; } -Future User::Reload() { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::UpdatePhoneNumberCredentialLastResult_DEPRECATED() + const { + return static_cast &>( + future_data_.future_impl.LastResult( + kUserFn_UpdatePhoneNumberCredential_DEPRECATED)); +} + +Future UserInternal::Reload() { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_Reload, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, + &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Reload); - JNIEnv* env = Env(auth_data_); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kReload)); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_Reload); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + JNIEnv *env = Env(auth_data_); + jobject pending_result = + env->CallObjectMethod(user_, user::GetMethodId(user::kReload)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -Future User::Reauthenticate(const Credential& credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::ReloadLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_Reload)); +} + +Future UserInternal::Reauthenticate(const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture( + kUserFn_Reauthenticate, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Reauthenticate); - JNIEnv* env = Env(auth_data_); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kReauthenticate), - CredentialFromImpl(credential.impl_)); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_Reload); + Future future = MakeFuture(&future_data_.future_impl, future_handle); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); + JNIEnv *env = Env(auth_data_); + jobject pending_result = + env->CallObjectMethod(user_, user::GetMethodId(user::kReauthenticate), + CredentialFromImpl(credential.impl_)); + + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, nullptr); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -Future User::ReauthenticateAndRetrieveData_DEPRECATED( - const Credential& credential) { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::ReauthenticateLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_Reauthenticate)); +} + +Future UserInternal::ReauthenticateAndRetrieveData_DEPRECATED( + const Credential &credential) { + MutexLock user_info_lock(user_mutex_); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); + Future future = + MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, SignInResult()); + return future; } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc( - kUserFn_ReauthenticateAndRetrieveData_DEPRECATED); - JNIEnv* env = Env(auth_data_); + JNIEnv *env = Env(auth_data_); jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), - user::GetMethodId(user::kReauthenticateAndRetrieveData), + user_, user::GetMethodId(user::kReauthenticateAndRetrieveData), CredentialFromImpl(credential.impl_)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, ReadSignInResult); + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, ReadSignInResult); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -Future User::ReauthenticateWithProvider_DEPRECATED( - FederatedAuthProvider* provider) const { - FIREBASE_ASSERT_RETURN(Future(), provider); - return provider->Reauthenticate(auth_data_); +Future +UserInternal::ReauthenticateAndRetrieveDataLastResult_DEPRECATED() const { + return static_cast &>( + future_data_.future_impl.LastResult( + kUserFn_ReauthenticateAndRetrieveData_DEPRECATED)); } -Future User::SendEmailVerification() { - if (!ValidUser(auth_data_)) { - return Future(); - } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_SendEmailVerification); - JNIEnv* env = Env(auth_data_); - - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kSendEmailVerification)); - - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, nullptr); - env->DeleteLocalRef(pending_result); +Future UserInternal::ReauthenticateWithProvider_DEPRECATED( + FederatedAuthProvider *provider) { + MutexLock user_info_lock(user_mutex_); + if (!is_valid() || provider == nullptr) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc( + kUserFn_ReauthenticateWithProvider_DEPRECATED); + Future future = + MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, + future_handle, &future_data_, SignInResult()); + } else { + CompleteFuture(kAuthErrorInvalidParameter, + kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } + return future; } - return MakeFuture(&futures, handle); + return provider->Reauthenticate(auth_data_, this); } -Future User::Delete() { - if (!ValidUser(auth_data_)) { - return Future(); +Future UserInternal::Delete() { + MutexLock user_info_lock(user_mutex_); + if (!is_valid()) { + return CreateAndCompleteFuture(kUserFn_Delete, kAuthErrorInvalidUser, + kUserNotInitializedErrorMessage, + &future_data_); } - ReferenceCountedFutureImpl& futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kUserFn_Delete); - JNIEnv* env = Env(auth_data_); - jobject pending_result = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kDelete)); + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_Reload); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + JNIEnv *env = Env(auth_data_); + jobject pending_result = + env->CallObjectMethod(user_, user::GetMethodId(user::kDelete)); - if (!CheckAndCompleteFutureOnError(env, &futures, handle)) { - RegisterCallback(pending_result, handle, auth_data_, - [](jobject result, FutureCallbackData* d, - bool success, void* void_data) { + if (!CheckAndCompleteFutureOnError(env, &future_data_.future_impl, + future_handle)) { + RegisterCallback(auth_data_, pending_result, future_handle, future_api_id_, + &future_data_.future_impl, + [](jobject result, FutureCallbackData *d, + bool success, void *void_data) { if (success) { - UpdateCurrentUser(d->auth_data); + UpdateCurrentUser(Env(d->auth_data), d->auth_data); } }); env->DeleteLocalRef(pending_result); } - return MakeFuture(&futures, handle); + return future; } -UserMetadata User::metadata() const { - if (!ValidUser(auth_data_)) return UserMetadata(); +Future UserInternal::DeleteLastResult() const { + return static_cast &>( + future_data_.future_impl.LastResult(kUserFn_Delete)); +} - JNIEnv* env = Env(auth_data_); +UserMetadata UserInternal::metadata() const { + UserMetadata user_metadata; + if (!is_valid()) return user_metadata; - jobject userMetadata = env->CallObjectMethod( - UserImpl(auth_data_), user::GetMethodId(user::kGetMetadata)); + JNIEnv *env = Env(auth_data_); + jobject jUserMetadata = + env->CallObjectMethod(user_, user::GetMethodId(user::kGetMetadata)); util::CheckAndClearJniExceptions(env); - if (!userMetadata) return UserMetadata(); + if (!jUserMetadata) return user_metadata; - UserMetadata data; - data.last_sign_in_timestamp = env->CallLongMethod( - userMetadata, metadata::GetMethodId(metadata::kGetLastSignInTimestamp)); + user_metadata.last_sign_in_timestamp = env->CallLongMethod( + jUserMetadata, metadata::GetMethodId(metadata::kGetLastSignInTimestamp)); assert(env->ExceptionCheck() == false); - data.creation_timestamp = env->CallLongMethod( - userMetadata, metadata::GetMethodId(metadata::kGetCreationTimestamp)); + user_metadata.creation_timestamp = env->CallLongMethod( + jUserMetadata, metadata::GetMethodId(metadata::kGetCreationTimestamp)); assert(env->ExceptionCheck() == false); - env->DeleteLocalRef(userMetadata); + env->DeleteLocalRef(jUserMetadata); - return data; + return user_metadata; } -bool User::is_email_verified() const { - if (!ValidUser(auth_data_)) return false; +bool UserInternal::is_email_verified() const { + if (!is_valid()) return false; - JNIEnv* env = Env(auth_data_); + JNIEnv *env = Env(auth_data_); bool result = env->CallBooleanMethod( - UserImpl(auth_data_), userinfo::GetMethodId(userinfo::kIsEmailVerified)); + user_, userinfo::GetMethodId(userinfo::kIsEmailVerified)); util::CheckAndClearJniExceptions(env); return result; } -bool User::is_anonymous() const { - if (!ValidUser(auth_data_)) return false; +bool UserInternal::is_anonymous() const { + if (!is_valid()) return false; - JNIEnv* env = Env(auth_data_); - bool result = env->CallBooleanMethod(UserImpl(auth_data_), - user::GetMethodId(user::kIsAnonymous)); + JNIEnv *env = Env(auth_data_); + bool result = + env->CallBooleanMethod(user_, user::GetMethodId(user::kIsAnonymous)); util::CheckAndClearJniExceptions(env); return result; } +std::string UserInternal::uid() const { + if (!is_valid()) return ""; + JNIEnv *env = Env(auth_data_); + jobject property = + env->CallObjectMethod(user_, userinfo::GetMethodId(userinfo::kGetUid)); + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { + return std::string(); + } + return JniStringToString(env, property); +} + +std::string UserInternal::email() const { + if (!is_valid()) return ""; + JNIEnv *env = Env(auth_data_); + jobject property = + env->CallObjectMethod(user_, userinfo::GetMethodId(userinfo::kGetEmail)); + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { + return std::string(); + } + return JniStringToString(env, property); +} + +std::string UserInternal::display_name() const { + if (!is_valid()) return ""; + JNIEnv *env = Env(auth_data_); + jobject property = env->CallObjectMethod( + user_, userinfo::GetMethodId(userinfo::kGetDisplayName)); + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { + return std::string(); + } + return JniStringToString(env, property); +} + +std::string UserInternal::photo_url() const { + if (!is_valid()) return ""; + JNIEnv *env = Env(auth_data_); + jobject property = env->CallObjectMethod( + user_, userinfo::GetMethodId(userinfo::kGetPhotoUrl)); + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { + return std::string(); + } + return JniUriToString(env, property); +} + +std::string UserInternal::provider_id() const { + if (!is_valid()) return ""; + JNIEnv *env = Env(auth_data_); + jobject property = env->CallObjectMethod( + user_, userinfo::GetMethodId(userinfo::kGetProviderId)); + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { + return std::string(); + } + return JniStringToString(env, property); +} + +std::string UserInternal::phone_number() const { + if (!is_valid()) return ""; + JNIEnv *env = Env(auth_data_); + jobject property = env->CallObjectMethod( + user_, userinfo::GetMethodId(userinfo::kGetPhoneNumber)); + if (firebase::util::CheckAndClearJniExceptions(env) || !property) { + return std::string(); + } + return JniStringToString(env, property); +} + } // namespace auth } // namespace firebase diff --git a/auth/src/auth.cc b/auth/src/auth.cc index a7bd564e53..40680df32c 100644 --- a/auth/src/auth.cc +++ b/auth/src/auth.cc @@ -134,48 +134,55 @@ Auth::Auth(App* app, void* auth_impl) : auth_data_(new AuthData) { } void Auth::DeleteInternal() { - MutexLock lock(*g_auths_mutex); + // Mutex is contained within the auth_data_ object. Retain a pointer to it so + // that we can clean up its contents and then delete it after we leave the + // mutex. + AuthData* retained_auth_impl = auth_data_; + { + MutexLock(auth_data_->auth_mutex); + MutexLock lock(*g_auths_mutex); - if (!auth_data_) return; + if (!auth_data_) return; - { - MutexLock destructing_lock(auth_data_->desctruting_mutex); - auth_data_->destructing = true; - } + { + MutexLock destructing_lock(auth_data_->destructing_mutex); + auth_data_->destructing = true; + } - CleanupNotifier* notifier = CleanupNotifier::FindByOwner(auth_data_->app); - assert(notifier); - notifier->UnregisterObject(this); + CleanupNotifier* notifier = CleanupNotifier::FindByOwner(auth_data_->app); + assert(notifier); + notifier->UnregisterObject(this); - int num_auths_remaining = 0; - { - // Remove `this` from the g_auths map. - // The mapping is 1:1, so we should only ever delete one. - for (auto it = g_auths.begin(); it != g_auths.end(); ++it) { - if (it->second == this) { - LogDebug("Deleting Auth %p for App %p", this, it->first); - g_auths.erase(it); - break; + int num_auths_remaining = 0; + { + // Remove `this` from the g_auths map. + // The mapping is 1:1, so we should only ever delete one. + for (auto it = g_auths.begin(); it != g_auths.end(); ++it) { + if (it->second == this) { + LogDebug("Deleting Auth %p for App %p", this, it->first); + g_auths.erase(it); + break; + } } - } - num_auths_remaining = g_auths.size(); - } + num_auths_remaining = g_auths.size(); + } - auth_data_->ClearListeners(); + auth_data_->ClearListeners(); - // If this is the last Auth instance to be cleaned up, also clean up data for - // Credentials. - if (num_auths_remaining == 0) { - CleanupCredentialFutureImpl(); - } + // If this is the last Auth instance to be cleaned up, also clean up data + // for Credentials. + if (num_auths_remaining == 0) { + CleanupCredentialFutureImpl(); + } - // Destroy the platform-specific object. - DestroyPlatformAuth(auth_data_); + // Destroy the platform-specific object. + DestroyPlatformAuth(auth_data_); + auth_data_ = nullptr; + } // Delete the pimpl data. - delete auth_data_; - auth_data_ = nullptr; + delete retained_auth_impl; } Auth::~Auth() { DeleteInternal(); } @@ -183,6 +190,7 @@ Auth::~Auth() { DeleteInternal(); } // Always non-nullptr since set in constructor. App& Auth::app() { FIREBASE_ASSERT(auth_data_ != nullptr); + MutexLock(auth_data_->auth_mutex); return *auth_data_->app; } @@ -217,6 +225,7 @@ static bool AddListener(T listener, std::vector* listener_vector, Auth* auth, void Auth::AddAuthStateListener(AuthStateListener* listener) { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); // Would have to lock mutex till the method ends to protect on race // conditions. MutexLock lock(auth_data_->listeners_mutex); @@ -235,6 +244,7 @@ void Auth::AddAuthStateListener(AuthStateListener* listener) { void Auth::AddIdTokenListener(IdTokenListener* listener) { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); // Would have to lock mutex till the method ends to protect on race // conditions. MutexLock lock(auth_data_->listeners_mutex); @@ -289,12 +299,14 @@ static void RemoveListener(T listener, std::vector* listener_vector, void Auth::RemoveAuthStateListener(AuthStateListener* listener) { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); RemoveListener(listener, &auth_data_->listeners, this, &listener->auths_, &auth_data_->listeners_mutex); } void Auth::RemoveIdTokenListener(IdTokenListener* listener) { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); int listener_count = auth_data_->id_token_listeners.size(); RemoveListener(listener, &auth_data_->id_token_listeners, this, &listener->auths_, &auth_data_->listeners_mutex); diff --git a/auth/src/common.cc b/auth/src/common.cc index 510d1f82c0..165c8c6cfd 100644 --- a/auth/src/common.cc +++ b/auth/src/common.cc @@ -22,9 +22,15 @@ namespace firebase { namespace auth { const char* kUserNotInitializedErrorMessage = - "Operation attmpted on an invalid User object."; + "Operation attempted on an invalid User object."; const char* kPhoneAuthNotSupportedErrorMessage = "Phone Auth is not supported on this platform."; +const char* kAuthInvalidParameterErrorMessage = + "A parameter pass to the auth method is null or invalid."; +extern const char* kInvalidCredentialErrorMessage = + "The provided credential does not match the required type."; +extern const char* kErrorEmptyEmailPasswordErrorMessage = + "Empty email or password are not allowed."; // static member variables const uint32_t PhoneAuthProvider::kMaxTimeoutMs = 3000; diff --git a/auth/src/common.h b/auth/src/common.h index 80674ab2bd..0079c9eb61 100644 --- a/auth/src/common.h +++ b/auth/src/common.h @@ -28,6 +28,9 @@ namespace auth { // the AdErrorCode enumeration in the C++ API. extern const char* kUserNotInitializedErrorMessage; extern const char* kPhoneAuthNotSupportedErrorMessage; +extern const char* kAuthInvalidParameterErrorMessage; +extern const char* kInvalidCredentialErrorMessage; +extern const char* kErrorEmptyEmailPasswordErrorMessage; // Enumeration for Credential API functions that return a Future. // This allows us to hold a Future for the most recent call to that API. @@ -46,12 +49,6 @@ struct FutureData { ReferenceCountedFutureImpl future_impl; }; -template -struct FutureCallbackData { - FutureData* future_data; - SafeFutureHandle future_handle; -}; - // Create a future and update the corresponding last result. template SafeFutureHandle CreateFuture(int fn_idx, FutureData* future_data) { @@ -131,9 +128,6 @@ void NotifyAuthStateListeners(AuthData* auth_data); // Notify all the listeners of the ID token change. void NotifyIdTokenListeners(AuthData* auth_data); -// Synchronize the current user. -void UpdateCurrentUser(AuthData* auth_data); - // Get a FutureImpl to use for Credential methods that return Futures. ReferenceCountedFutureImpl* GetCredentialFutureImpl(); diff --git a/auth/src/data.h b/auth/src/data.h index 54a09264c7..529355f951 100644 --- a/auth/src/data.h +++ b/auth/src/data.h @@ -39,6 +39,9 @@ struct AuthDataDeprecatedFields { // pointer the platform specific user object, which is updated on User // operations. UserInternal* user_internal_deprecated; + + // JNI reference to the user object in the Firebase Android SDK. + void* android_user_impl; }; // Enumeration for API functions that return a Future. @@ -195,7 +198,10 @@ struct AuthData { bool destructing; // Mutex protecting destructing - Mutex desctruting_mutex; + Mutex destructing_mutex; + + // Mutex guarding the auth object for standard API operations. + Mutex auth_mutex; // Sets if the Id Token Listener is expecting a callback. // Used to workaround an issue where the Id Token is not reset with a new one, diff --git a/auth/src/desktop/user_desktop.cc b/auth/src/desktop/user_desktop.cc index 742875103b..25d15127e2 100644 --- a/auth/src/desktop/user_desktop.cc +++ b/auth/src/desktop/user_desktop.cc @@ -511,7 +511,7 @@ void AssignLoadedData(const Future& future, AuthData* auth_data) { void HandleLoadedData(const Future& future, void* auth_data) { auto cast_auth_data = static_cast(auth_data); - MutexLock destructing_lock(cast_auth_data->desctruting_mutex); + MutexLock destructing_lock(cast_auth_data->destructing_mutex); if (cast_auth_data->destructing) { // If auth is destructing, abort. return; diff --git a/auth/src/include/firebase/auth/types.h b/auth/src/include/firebase/auth/types.h index 1627e37f8a..4c0fe9c0be 100644 --- a/auth/src/include/firebase/auth/types.h +++ b/auth/src/include/firebase/auth/types.h @@ -429,8 +429,11 @@ enum AuthError { #endif // INTERNAL_EXEPERIMENTAL - /// An operation was attempted on an invalid User. + /// Indicates that an operation was attempted on an invalid User. kAuthErrorInvalidUser, + + /// Indicates that an invalid parameter was passed to an auth method. + kAuthErrorInvalidParameter, }; /// @brief Contains information required to authenticate with a third party diff --git a/auth/src/include/firebase/auth/user.h b/auth/src/include/firebase/auth/user.h index 719446266b..5278c7d593 100644 --- a/auth/src/include/firebase/auth/user.h +++ b/auth/src/include/firebase/auth/user.h @@ -386,7 +386,7 @@ class User : public UserInfoInterface { /// platforms. On other platforms this method will return a Future with a /// preset error code: kAuthErrorUnimplemented. FIREBASE_DEPRECATED Future LinkWithProvider_DEPRECATED( - FederatedAuthProvider* provider) const; + FederatedAuthProvider* provider); /// @deprecated This is a deprecated method. Please use @ref Unlink(const /// char*) instead. @@ -523,11 +523,6 @@ class User : public UserInfoInterface { virtual std::string phone_number() const; private: - // @deprecated User references to auth_data should only be needed during - // the Google I/O 23 breaking changes deprecation window. - // - // Internal only. - // // Constructor of an internal opaque type. Memory ownership of UserInternal // passes to to this User object. User(AuthData* auth_data, UserInternal* user_internal); diff --git a/auth/src/ios/auth_ios.mm b/auth/src/ios/auth_ios.mm index 428f3ab80b..af60ff8ac0 100644 --- a/auth/src/ios/auth_ios.mm +++ b/auth/src/ios/auth_ios.mm @@ -149,7 +149,7 @@ explicit ListenerHandleHolder(T handle) : handle(handle) {} // Grab the user value from the iOS API and remember it locally. void UpdateCurrentUser(AuthData *auth_data) { - MutexLock lock(auth_data->future_impl.mutex()); + MutexLock(auth_data->auth_mutex); FIRUser *user = [AuthImpl(auth_data) currentUser]; SetUserImpl(auth_data, user); } @@ -202,6 +202,7 @@ void UpdateCurrentUser(AuthData *auth_data) { // Platform-specific method to destroy the wrapped Auth class. void Auth::DestroyPlatformAuth(AuthData *auth_data) { + // Note: auth_data->auth_mutex is already locked by Auth::DeleteInternal(). // Remove references from listener blocks. AuthDataIos *auth_data_ios = reinterpret_cast(auth_data->auth_impl); FIRCPPAuthListenerHandle *listener_cpp_handle = auth_data_ios->listener_handle.get(); @@ -243,18 +244,19 @@ void LogHeartbeat(Auth *auth) { } Future Auth::FetchProvidersForEmail(const char *email) { + MutexLock(auth_data_->auth_mutex); // Create data structure to hold asynchronous results. FetchProvidersResult initial_data; - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_FetchProvidersForEmail, initial_data); - + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_FetchProvidersForEmail, initial_data); + Future future = MakeFuture(&future_impl, future_handle); [AuthImpl(auth_data_) fetchSignInMethodsForEmail:@(email) completion:^(NSArray *_Nullable providers, NSError *_Nullable error) { - futures.Complete( - handle, AuthErrorFromNSError(error), + future_impl.Complete( + future_handle, AuthErrorFromNSError(error), [error.localizedDescription UTF8String], [providers](FetchProvidersResult *data) { // Copy data to our result format. @@ -265,8 +267,7 @@ void LogHeartbeat(Auth *auth) { } }); }]; - - return MakeFuture(&futures, handle); + return future; } // Support the deprecated current_user method by returning a pointer to the @@ -275,7 +276,7 @@ void LogHeartbeat(Auth *auth) { // window. User *Auth::current_user_DEPRECATED() { if (!auth_data_) return nullptr; - MutexLock lock(auth_data_->future_impl.mutex()); + MutexLock(auth_data_->auth_mutex); if (auth_data_->deprecated_fields.user_deprecated == nullptr || !auth_data_->deprecated_fields.user_deprecated->is_valid()) { return nullptr; @@ -286,7 +287,7 @@ void LogHeartbeat(Auth *auth) { static User *AssignUser(FIRUser *_Nullable user, AuthData *auth_data) { // Update our pointer to the iOS user that we're wrapping. - MutexLock lock(auth_data->future_impl.mutex()); + MutexLock(auth_data->auth_mutex); if (user) { SetUserImpl(auth_data, user); } @@ -296,6 +297,7 @@ void LogHeartbeat(Auth *auth) { std::string Auth::language_code() const { if (!auth_data_) return ""; + MutexLock(auth_data_->auth_mutex); NSString *language_code = [AuthImpl(auth_data_) languageCode]; if (language_code == nil) { return std::string(); @@ -306,6 +308,7 @@ void LogHeartbeat(Auth *auth) { void Auth::set_language_code(const char *language_code) { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); NSString *code; if (language_code != nullptr) { code = [NSString stringWithUTF8String:language_code]; @@ -315,6 +318,7 @@ void LogHeartbeat(Auth *auth) { void Auth::UseAppLanguage() { if (!auth_data_) return; + MutexLock(auth_data_->auth_mutex); [AuthImpl(auth_data_) useAppLanguage]; } @@ -329,13 +333,13 @@ AuthError AuthErrorFromNSError(NSError *_Nullable error) { } void SignInCallback(FIRUser *_Nullable user, NSError *_Nullable error, - SafeFutureHandle handle, ReferenceCountedFutureImpl &future_impl, + SafeFutureHandle future_handle, ReferenceCountedFutureImpl &future_impl, AuthData *auth_data) { User *result = AssignUser(user, auth_data); - if (future_impl.ValidFuture(handle)) { + if (future_impl.ValidFuture(future_handle)) { // Finish off the asynchronous call so that the caller can read it. - future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + future_impl.CompleteWithResult(future_handle, AuthErrorFromNSError(error), util::NSStringToString(error.localizedDescription).c_str(), result); } @@ -343,16 +347,16 @@ void SignInCallback(FIRUser *_Nullable user, NSError *_Nullable error, void SignInResultWithProviderCallback( FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error, - SafeFutureHandle handle, ReferenceCountedFutureImpl &future_impl, + SafeFutureHandle future_handle, ReferenceCountedFutureImpl &future_impl, AuthData *_Nonnull auth_data, const FIROAuthProvider *_Nonnull ios_auth_provider /*unused */) { // ios_auth_provider exists as a parameter to hold a reference to the FIROAuthProvider preventing // its release by the Objective-C runtime during the asynchronous SignIn operation. error = RemapBadProviderIDErrors(error); - SignInResultCallback(auth_result, error, handle, future_impl, auth_data); + SignInResultCallback(auth_result, error, future_handle, future_impl, auth_data); } void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error, - SafeFutureHandle handle, + SafeFutureHandle future_handle, ReferenceCountedFutureImpl &future_impl, AuthData *auth_data) { User *user = AssignUser(auth_result.user, auth_data); @@ -373,52 +377,56 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu } } - if (future_impl.ValidFuture(handle)) { - future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + if (future_impl.ValidFuture(future_handle)) { + future_impl.CompleteWithResult(future_handle, AuthErrorFromNSError(error), util::NSStringToString(error.localizedDescription).c_str(), result); } } Future Auth::SignInWithCustomToken_DEPRECATED(const char *token) { - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED, nullptr); - + MutexLock(auth_data_->auth_mutex); + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_SignInWithCustomToken_DEPRECATED, nullptr); + Future future = MakeFuture(&future_impl, future_handle); [AuthImpl(auth_data_) signInWithCustomToken:@(token) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, futures, auth_data_); + SignInCallback(auth_result.user, error, future_handle, future_impl, auth_data_); }]; - return MakeFuture(&futures, handle); + return future; } Future Auth::SignInWithCredential_DEPRECATED(const Credential &credential) { - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED, nullptr); - + MutexLock(auth_data_->auth_mutex); + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_SignInWithCredential_DEPRECATED, nullptr); + Future future = MakeFuture(&future_impl, future_handle); [AuthImpl(auth_data_) signInWithCredential:CredentialFromImpl(credential.impl_) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, futures, auth_data_); + SignInCallback(auth_result.user, error, future_handle, future_impl, auth_data_); }]; - return MakeFuture(&futures, handle); + return future; } Future Auth::SignInAndRetrieveDataWithCredential_DEPRECATED( const Credential &credential) { - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc( + MutexLock(auth_data_->auth_mutex); + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = future_impl.SafeAlloc( kAuthFn_SignInAndRetrieveDataWithCredential_DEPRECATED, SignInResult()); - + Future future = MakeFuture(&future_impl, future_handle); [AuthImpl(auth_data_) signInWithCredential:CredentialFromImpl(credential.impl_) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInResultCallback(auth_result, error, handle, futures, auth_data_); + SignInResultCallback(auth_result, error, future_handle, future_impl, auth_data_); }]; - - return MakeFuture(&futures, handle); + return future; } Future Auth::SignInWithProvider_DEPRECATED(FederatedAuthProvider *provider) { @@ -427,59 +435,67 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu } Future Auth::SignInAnonymously_DEPRECATED() { - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = + MutexLock(auth_data_->auth_mutex); + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = auth_data_->future_impl.SafeAlloc(kAuthFn_SignInAnonymously_DEPRECATED, nullptr); - + Future future = MakeFuture(&future_impl, future_handle); [AuthImpl(auth_data_) signInAnonymouslyWithCompletion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, futures, auth_data_); + SignInCallback(auth_result.user, error, future_handle, future_impl, auth_data_); }]; - - return MakeFuture(&futures, handle); + return future; } Future Auth::SignInWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED, nullptr); + MutexLock(auth_data_->auth_mutex); + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_SignInWithEmailAndPassword_DEPRECATED, nullptr); + Future future = MakeFuture(&future_impl, future_handle); if (!email || strlen(email) == 0) { - futures.Complete(handle, kAuthErrorMissingEmail, "Empty email is not allowed."); + future_impl.Complete(future_handle, kAuthErrorMissingEmail, "Empty email is not allowed."); } else if (!password || strlen(password) == 0) { - futures.Complete(handle, kAuthErrorMissingPassword, "Empty password is not allowed."); + future_impl.Complete(future_handle, kAuthErrorMissingPassword, + "Empty password is not allowed."); } else { [AuthImpl(auth_data_) signInWithEmail:@(email) password:@(password) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, futures, auth_data_); + SignInCallback(auth_result.user, error, future_handle, future_impl, auth_data_); }]; } - return MakeFuture(&futures, handle); + return future; } Future Auth::CreateUserWithEmailAndPassword_DEPRECATED(const char *email, const char *password) { - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED, nullptr); + MutexLock(auth_data_->auth_mutex); + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_CreateUserWithEmailAndPassword_DEPRECATED, nullptr); + Future future = MakeFuture(&future_impl, future_handle); if (!email || strlen(email) == 0) { - futures.Complete(handle, kAuthErrorMissingEmail, "Empty email is not allowed."); + future_impl.Complete(future_handle, kAuthErrorMissingEmail, + kErrorEmptyEmailPasswordErrorMessage); } else if (!password || strlen(password) == 0) { - futures.Complete(handle, kAuthErrorMissingPassword, "Empty password is not allowed."); + future_impl.Complete(future_handle, kAuthErrorMissingPassword, + kErrorEmptyEmailPasswordErrorMessage); } else { [AuthImpl(auth_data_) createUserWithEmail:@(email) password:@(password) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - SignInCallback(auth_result.user, error, handle, futures, auth_data_); + SignInCallback(auth_result.user, error, future_handle, future_impl, auth_data_); }]; } - return MakeFuture(&futures, handle); + return future; } void Auth::SignOut() { + MutexLock(auth_data_->auth_mutex); // TODO(jsanmiya): Verify with iOS team why this returns an error. NSError *_Nullable error; [AuthImpl(auth_data_) signOut:&error]; @@ -487,16 +503,17 @@ void SignInResultCallback(FIRAuthDataResult *_Nullable auth_result, NSError *_Nu } Future Auth::SendPasswordResetEmail(const char *email) { - ReferenceCountedFutureImpl &futures = auth_data_->future_impl; - const auto handle = futures.SafeAlloc(kAuthFn_SendPasswordResetEmail); - - [AuthImpl(auth_data_) sendPasswordResetWithEmail:@(email) - completion:^(NSError *_Nullable error) { - futures.Complete(handle, AuthErrorFromNSError(error), - [error.localizedDescription UTF8String]); - }]; - - return MakeFuture(&futures, handle); + MutexLock(auth_data_->auth_mutex); + ReferenceCountedFutureImpl &future_impl = auth_data_->future_impl; + const auto future_handle = future_impl.SafeAlloc(kAuthFn_SendPasswordResetEmail); + Future future = MakeFuture(&future_impl, future_handle); + [AuthImpl(auth_data_) + sendPasswordResetWithEmail:@(email) + completion:^(NSError *_Nullable error) { + future_impl.Complete(future_handle, AuthErrorFromNSError(error), + [error.localizedDescription UTF8String]); + }]; + return future; } // Remap iOS SDK errors reported by the UIDelegate. While these errors seem like diff --git a/auth/src/ios/common_ios.h b/auth/src/ios/common_ios.h index f5d8809752..4f9f655218 100644 --- a/auth/src/ios/common_ios.h +++ b/auth/src/ios/common_ios.h @@ -48,12 +48,23 @@ OBJ_C_PTR_WRAPPER(FIRAuthCredential); OBJ_C_PTR_WRAPPER(FIRUser); OBJ_C_PTR_WRAPPER(FIRCPPAuthListenerHandle); +// Synchronize the current user. +void UpdateCurrentUser(AuthData *auth_data); + // Auth implementation on iOS. struct AuthDataIos { FIRAuthPointer fir_auth; FIRCPPAuthListenerHandlePointer listener_handle; }; +// Struct to contain the data required to complete +// futures asynchronously on iOS. +template +struct FutureCallbackData { + FutureData *future_data; + SafeFutureHandle future_handle; +}; + // Contains the interface between the public API and the underlying // Obj-C SDK FirebaseUser implemention. class UserInternal { @@ -152,14 +163,12 @@ class UserInternal { // Used to support older method invocation of provider_data_DEPRECATED(). std::vector user_infos_; - // Guard the creation and deletion of the vector of UserInfoInterface* - // allocations in provider_data_DEPRECATED(). - Mutex user_info_mutex_deprecated_; - // Guard against changes to the user_ object. Mutex user_mutex_; }; +/// @deprecated +/// /// Replace the platform-dependent FIRUser object. /// Note: this function is only used to support DEPRECATED methods which return User*. This /// functionality should be removed when those deprecated methods are removed. diff --git a/auth/src/ios/credential_ios.mm b/auth/src/ios/credential_ios.mm index 8a6daaaba7..5fbade9c73 100644 --- a/auth/src/ios/credential_ios.mm +++ b/auth/src/ios/credential_ios.mm @@ -170,10 +170,12 @@ @implementation PhoneListenerDataObjC // static Future GameCenterAuthProvider::GetCredential() { - auto future_api = GetCredentialFutureImpl(); - FIREBASE_ASSERT(future_api != nullptr); + ReferenceCountedFutureImpl* future_impl = GetCredentialFutureImpl(); + FIREBASE_ASSERT(future_impl != nullptr); + const auto future_handle = + future_impl->SafeAlloc(kCredentialFn_GameCenterGetCredential); + Future future = MakeFuture(future_impl, future_handle); - const auto handle = future_api->SafeAlloc(kCredentialFn_GameCenterGetCredential); /** Linking GameKit.framework without using it on macOS results in App Store rejection. Thus we don't link GameKit.framework to our SDK directly. `optionalLocalPlayer` is used for @@ -184,20 +186,19 @@ @implementation PhoneListenerDataObjC // Early-out if GameKit is not linked if (!optionalLocalPlayer) { - future_api->Complete(handle, kAuthErrorInvalidCredential, - "GameCenter authentication is unavailable - missing GameKit capability."); - return MakeFuture(future_api, handle); + future_impl->Complete(future_handle, kAuthErrorInvalidCredential, + "GameCenter authentication is unavailable - missing GameKit capability."); + } else { + [FIRGameCenterAuthProvider + getCredentialWithCompletion:^(FIRAuthCredential* _Nullable credential, + NSError* _Nullable error) { + Credential result(new FIRAuthCredentialPointer(credential)); + future_impl->CompleteWithResult( + future_handle, AuthErrorFromNSError(error), + util::NSStringToString(error.localizedDescription).c_str(), result); + }]; } - - [FIRGameCenterAuthProvider getCredentialWithCompletion:^(FIRAuthCredential* _Nullable credential, - NSError* _Nullable error) { - Credential result(new FIRAuthCredentialPointer(credential)); - future_api->CompleteWithResult(handle, AuthErrorFromNSError(error), - util::NSStringToString(error.localizedDescription).c_str(), - result); - }]; - - return MakeFuture(future_api, handle); + return future; } // static @@ -407,19 +408,19 @@ explicit PhoneAuthProviderData(FIRPhoneAuthProvider* objc_provider) // current API. void LinkWithProviderGetCredentialCallback(FIRAuthCredential* _Nullable credential, NSError* _Nullable error, - SafeFutureHandle handle, + SafeFutureHandle future_handle, ReferenceCountedFutureImpl& future_impl, AuthData* auth_data, FIRUser* user, const FIROAuthProvider* ios_auth_provider) { if (error && error.code != 0) { error = RemapBadProviderIDErrors(error); - future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + future_impl.CompleteWithResult(future_handle, AuthErrorFromNSError(error), util::NSStringToString(error.localizedDescription).c_str(), SignInResult()); } else { [user linkWithCredential:credential completion:^(FIRAuthDataResult* _Nullable auth_result, NSError* _Nullable error) { - SignInResultWithProviderCallback(auth_result, error, handle, future_impl, + SignInResultWithProviderCallback(auth_result, error, future_handle, future_impl, auth_data, ios_auth_provider); }]; } @@ -430,20 +431,20 @@ void LinkWithProviderGetCredentialCallback(FIRAuthCredential* _Nullable credenti // accessible via their current API. void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullable credential, NSError* _Nullable error, - SafeFutureHandle handle, + SafeFutureHandle future_handle, ReferenceCountedFutureImpl& future_impl, AuthData* auth_data, FIRUser* user, const FIROAuthProvider* ios_auth_provider) { if (error && error.code != 0) { error = RemapBadProviderIDErrors(error); - future_impl.CompleteWithResult(handle, AuthErrorFromNSError(error), + future_impl.CompleteWithResult(future_handle, AuthErrorFromNSError(error), util::NSStringToString(error.localizedDescription).c_str(), SignInResult()); } else { [user reauthenticateWithCredential:credential completion:^(FIRAuthDataResult* _Nullable auth_result, NSError* _Nullable error) { - SignInResultWithProviderCallback(auth_result, error, handle, + SignInResultWithProviderCallback(auth_result, error, future_handle, future_impl, auth_data, ios_auth_provider); }]; @@ -452,9 +453,11 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl Future FederatedOAuthProvider::SignIn(AuthData* auth_data) { assert(auth_data); - ReferenceCountedFutureImpl& futures = auth_data->future_impl; - const auto handle = - futures.SafeAlloc(kAuthFn_SignInWithProvider_DEPRECATED, SignInResult()); + ReferenceCountedFutureImpl& future_impl = auth_data->future_impl; + const auto future_handle = + future_impl.SafeAlloc(kAuthFn_SignInWithProvider_DEPRECATED, SignInResult()); + Future future = MakeFuture(&future_impl, future_handle); + FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) auth:AuthImpl(auth_data)]; @@ -465,24 +468,25 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl signInWithProvider:ios_provider UIDelegate:nullptr completion:^(FIRAuthDataResult* _Nullable auth_result, NSError* _Nullable error) { - SignInResultWithProviderCallback(auth_result, error, handle, futures, auth_data, - ios_provider); + SignInResultWithProviderCallback(auth_result, error, future_handle, future_impl, + auth_data, ios_provider); }]; - return MakeFuture(&futures, handle); } else { - Future future = MakeFuture(&futures, handle); - futures.CompleteWithResult(handle, kAuthErrorFailure, "Internal error constructing provider.", - SignInResult()); - return future; + future_impl.CompleteWithResult(future_handle, kAuthErrorFailure, + "Internal error constructing provider.", SignInResult()); } + return future; } Future FederatedOAuthProvider::Link(AuthData* auth_data, UserInternal* user_internal) { assert(auth_data); assert(user_internal); - auto handle = user_internal->future_data_.future_impl.SafeAlloc( - kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + ReferenceCountedFutureImpl& future_impl = user_internal->future_data_.future_impl; + auto future_handle = + future_impl.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + Future future = MakeFuture(&future_impl, future_handle); + #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) @@ -493,36 +497,36 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl FIRUser* user = user_internal->user_; // TODO(b/138788092) invoke FIRUser linkWithProvider instead, once that method is added to the // iOS SDK. - [ios_provider - getCredentialWithUIDelegate:nullptr - completion:^(FIRAuthCredential* _Nullable credential, - NSError* _Nullable error) { - LinkWithProviderGetCredentialCallback( - credential, error, handle, user_internal->future_data_.future_impl, - auth_data, user, ios_provider); - }]; - return MakeFuture(&user_internal->future_data_.future_impl, handle); + [ios_provider getCredentialWithUIDelegate:nullptr + completion:^(FIRAuthCredential* _Nullable credential, + NSError* _Nullable error) { + LinkWithProviderGetCredentialCallback( + credential, error, future_handle, + user_internal->future_data_.future_impl, auth_data, user, + ios_provider); + }]; } else { - Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); - user_internal->future_data_.future_impl.CompleteWithResult( - handle, kAuthErrorFailure, "Internal error constructing provider.", SignInResult()); - return future; + future_impl.CompleteWithResult(future_handle, kAuthErrorFailure, + "Internal error constructing provider.", SignInResult()); } #else // non-iOS Apple platforms (eg: tvOS) - Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); - user_internal->future_data_.future_impl.Complete( - handle, kAuthErrorApiNotAvailable, - "OAuth provider linking is not supported on non-iOS Apple platforms."); + future_impl.CompleteWithResult( + future_handle, kAuthErrorApiNotAvailable, + "OAuth provider linking is not supported on non-iOS Apple platforms.", SignInResult()); #endif // FIREBASE_PLATFORM_IOS + return future; } Future FederatedOAuthProvider::Reauthenticate(AuthData* auth_data, UserInternal* user_internal) { assert(auth_data); assert(user_internal); - auto handle = user_internal->future_data_.future_impl.SafeAlloc( - kUserFn_LinkWithProvider_DEPRECATED, SignInResult()); + ReferenceCountedFutureImpl& future_impl = user_internal->future_data_.future_impl; + auto future_handle = future_impl.SafeAlloc( + kUserFn_ReauthenticateWithProvider_DEPRECATED, SignInResult()); + Future future = MakeFuture(&future_impl, future_handle); + #if FIREBASE_PLATFORM_IOS FIROAuthProvider* ios_provider = (FIROAuthProvider*)[FIROAuthProvider providerWithProviderID:@(provider_data_.provider_id.c_str()) @@ -533,28 +537,23 @@ void ReauthenticateWithProviderGetCredentialCallback(FIRAuthCredential* _Nullabl FIRUser* user = user_internal->user_; // TODO(b/138788092) invoke FIRUser:reuthenticateWithProvider instead, once that method is added // to the iOS SDK. - [ios_provider - getCredentialWithUIDelegate:nullptr - completion:^(FIRAuthCredential* _Nullable credential, - NSError* _Nullable error) { - ReauthenticateWithProviderGetCredentialCallback( - credential, error, handle, user_internal->future_data_.future_impl, - auth_data, user, ios_provider); - }]; - return MakeFuture(&user_internal->future_data_.future_impl, handle); + [ios_provider getCredentialWithUIDelegate:nullptr + completion:^(FIRAuthCredential* _Nullable credential, + NSError* _Nullable error) { + ReauthenticateWithProviderGetCredentialCallback( + credential, error, future_handle, future_impl, auth_data, + user, ios_provider); + }]; } else { - Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); - user_internal->future_data_.future_impl.CompleteWithResult( - handle, kAuthErrorFailure, "Internal error constructing provider.", SignInResult()); - return future; + future_impl.CompleteWithResult(future_handle, kAuthErrorFailure, + "Internal error constructing provider.", SignInResult()); } - #else // non-iOS Apple platforms (eg: tvOS) - Future future = MakeFuture(&user_internal->future_data_.future_impl, handle); - user_internal->future_data_.future_impl.Complete( - handle, kAuthErrorApiNotAvailable, - "OAuth reauthentication is not supported on non-iOS Apple platforms."); + future_impl.CompleteWithResult( + future_handle, kAuthErrorApiNotAvailable, + "OAuth reauthentication is not supported on non-iOS Apple platforms.", SignInResult()); #endif // FIREBASE_PLATFORM_IOS + return future; } } // namespace auth diff --git a/auth/src/ios/user_ios.mm b/auth/src/ios/user_ios.mm index 80d48c20c4..6882b3e6f8 100644 --- a/auth/src/ios/user_ios.mm +++ b/auth/src/ios/user_ios.mm @@ -36,6 +36,7 @@ /// User::User(AuthData *auth_data, UserInternal *user_internal) { assert(auth_data); + auth_data_ = auth_data; if (user_internal == nullptr) { // Create an invalid user internal. // This will return is_valid() false, and operations will fail. @@ -43,7 +44,18 @@ } else { user_internal_ = user_internal; } - auth_data_ = auth_data; +} + +User::User(const User &user) { + assert(user.auth_data_); + auth_data_ = user.auth_data_; + if (user.user_internal_ == nullptr) { + // Create an invalid user internal. + // This will return is_valid() false, and operations will fail. + user_internal_ = new UserInternal(nullptr); + } else { + user_internal_ = new UserInternal(user.user_internal_->user_); + } } User::~User() { @@ -171,7 +183,7 @@ return user_internal_->LinkAndRetrieveDataWithCredentialLastResult_DEPRECATED(); } -Future User::LinkWithProvider_DEPRECATED(FederatedAuthProvider *provider) const { +Future User::LinkWithProvider_DEPRECATED(FederatedAuthProvider *provider) { assert(user_internal_); return user_internal_->LinkWithProvider_DEPRECATED(auth_data_, provider); } @@ -290,15 +302,13 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { : user_(user_internal.user_), future_data_(kUserFnCount) {} UserInternal::~UserInternal() { - user_ = nil; - { - MutexLock user_info_lock(user_info_mutex_deprecated_); - clear_user_infos(); - } + MutexLock user_info_lock(user_mutex_); // Make sure we don't have any pending futures in flight before we disappear. while (!future_data_.future_impl.IsSafeToDelete()) { internal::Sleep(100); } + user_ = nil; + clear_user_infos(); } void UserInternal::set_native_user_object_deprecated(FIRUser *user) { @@ -352,7 +362,7 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { } const std::vector &UserInternal::provider_data_DEPRECATED() { - MutexLock user_info_lock(user_info_mutex_deprecated_); + MutexLock user_info_lock(user_mutex_); clear_user_infos(); if (is_valid()) { NSArray> *provider_data = user_.providerData; @@ -448,7 +458,6 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { [error.localizedDescription UTF8String]); delete callback_data; }]; - return future; } @@ -474,7 +483,6 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { [error.localizedDescription UTF8String]); delete callback_data; }]; - return future; } @@ -516,9 +524,8 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { Future UserInternal::LinkAndRetrieveDataWithCredential_DEPRECATED( AuthData *auth_data, const Credential &credential) { - // MutexLock user_info_lock(user_mutex_); + MutexLock user_info_lock(user_mutex_); if (!is_valid()) { - printf("DEDB LinkAndRetrieveDataWithCredential_DEPRECATED user is not valid\n"); SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( kUserFn_LinkAndRetrieveDataWithCredential_DEPRECATED); Future future = MakeFuture(&future_data_.future_impl, future_handle); @@ -534,11 +541,9 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { [user_ linkWithCredential:CredentialFromImpl(credential.impl_) completion:^(FIRAuthDataResult *_Nullable auth_result, NSError *_Nullable error) { - NSLog(@"DEDB Completion auth_result: %p error: %p\n", auth_result, error); SignInResultCallback(auth_result, error, callback_data->future_handle, callback_data->future_data->future_impl, auth_data); - NSLog(@"DEDB Completion SignInResultCallback returned\n"); - // delete callback_data; + delete callback_data; }]; return future; } @@ -550,8 +555,23 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { Future UserInternal::LinkWithProvider_DEPRECATED(AuthData *auth_data, FederatedAuthProvider *provider) { - FIREBASE_ASSERT_RETURN(Future(), provider); - return provider->Link(auth_data, this); + MutexLock user_info_lock(user_mutex_); + if (!is_valid() || provider == nullptr) { + SafeFutureHandle future_handle = + future_data_.future_impl.SafeAlloc(kUserFn_LinkWithProvider_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } else { + CompleteFuture(kAuthErrorInvalidParameter, kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } + return future; + } else { + return provider->Link(auth_data, this); + } } Future UserInternal::Unlink_DEPRECATED(AuthData *auth_data, const char *provider) { @@ -610,19 +630,17 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { delete callback_data; }]; } else { - CompleteFuture(kAuthErrorInvalidCredential, kInvalidCredentialMessage, + CompleteFuture(kAuthErrorInvalidCredential, kInvalidCredentialErrorMessage, callback_data->future_handle, &future_data_, (User *)nullptr); } - return future; - #else // non iOS Apple platforms (eg: tvOS). SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc(kUserFn_UpdatePhoneNumberCredential_DEPRECATED); Future future = MakeFuture(&future_data_.future_impl, future_handle); CompleteFuture(kAuthErrorApiNotAvailable, kPhoneAuthNotSupportedErrorMessage, future_handle, &future_data_, (User *)nullptr); - return future; #endif // FIREBASE_PLATFORM_IOS + return future; } Future UserInternal::Reload() { @@ -711,7 +729,20 @@ explicit IOSWrappedUserInfo(id user_info) : user_info_(user_info) { Future UserInternal::ReauthenticateWithProvider_DEPRECATED( AuthData *auth_data, FederatedAuthProvider *provider) { - FIREBASE_ASSERT_RETURN(Future(), provider); + MutexLock user_info_lock(user_mutex_); + if (!is_valid() || provider == nullptr) { + SafeFutureHandle future_handle = future_data_.future_impl.SafeAlloc( + kUserFn_ReauthenticateWithProvider_DEPRECATED); + Future future = MakeFuture(&future_data_.future_impl, future_handle); + if (!is_valid()) { + CompleteFuture(kAuthErrorInvalidUser, kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } else { + CompleteFuture(kAuthErrorInvalidParameter, kUserNotInitializedErrorMessage, future_handle, + &future_data_, SignInResult()); + } + return future; + } return provider->Reauthenticate(auth_data, this); }