Skip to content

Commit 6fc0194

Browse files
committed
update BoM version
1 parent 180db59 commit 6fc0194

File tree

11 files changed

+246
-137
lines changed

11 files changed

+246
-137
lines changed

auth/src/main/java/com/firebase/ui/auth/data/model/PendingIntentRequiredException.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.firebase.ui.auth.data.model;
22

33
import android.app.PendingIntent;
4+
import android.content.IntentSender;
45

56
import com.firebase.ui.auth.ErrorCodes;
67
import com.firebase.ui.auth.FirebaseUiException;
@@ -11,20 +12,54 @@
1112
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
1213
public class PendingIntentRequiredException extends FirebaseUiException {
1314
private final PendingIntent mPendingIntent;
15+
private final IntentSender mIntentSender;
1416
private final int mRequestCode;
1517

18+
/**
19+
* Constructor for cases when a PendingIntent is available.
20+
*
21+
* @param pendingIntent The PendingIntent required to complete the operation.
22+
* @param requestCode The associated request code.
23+
*/
1624
public PendingIntentRequiredException(@NonNull PendingIntent pendingIntent, int requestCode) {
1725
super(ErrorCodes.UNKNOWN_ERROR);
1826
mPendingIntent = pendingIntent;
27+
mIntentSender = null;
1928
mRequestCode = requestCode;
2029
}
2130

22-
@NonNull
31+
/**
32+
* Constructor for cases when an IntentSender is available.
33+
*
34+
* @param intentSender The IntentSender required to complete the operation.
35+
* @param requestCode The associated request code.
36+
*/
37+
public PendingIntentRequiredException(@NonNull IntentSender intentSender, int requestCode) {
38+
super(ErrorCodes.UNKNOWN_ERROR);
39+
mIntentSender = intentSender;
40+
mPendingIntent = null;
41+
mRequestCode = requestCode;
42+
}
43+
44+
/**
45+
* Returns the PendingIntent, if available.
46+
*
47+
* @return The PendingIntent or null if not available.
48+
*/
2349
public PendingIntent getPendingIntent() {
2450
return mPendingIntent;
2551
}
2652

53+
/**
54+
* Returns the IntentSender, if available.
55+
*
56+
* @return The IntentSender or null if not available.
57+
*/
58+
public IntentSender getIntentSender() {
59+
return mIntentSender;
60+
}
61+
2762
public int getRequestCode() {
2863
return mRequestCode;
2964
}
30-
}
65+
}

auth/src/main/java/com/firebase/ui/auth/ui/HelperActivityBase.java

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,8 @@
1010
import com.firebase.ui.auth.IdpResponse;
1111
import com.firebase.ui.auth.data.model.FlowParameters;
1212
import com.firebase.ui.auth.ui.credentials.CredentialSaveActivity;
13-
import com.firebase.ui.auth.ui.idp.AuthMethodPickerActivity;
14-
import com.firebase.ui.auth.util.CredentialUtils;
1513
import com.firebase.ui.auth.util.ExtraConstants;
16-
import com.firebase.ui.auth.util.data.ProviderUtils;
1714
import com.firebase.ui.auth.viewmodel.RequestCodes;
18-
import com.google.android.gms.auth.api.credentials.Credential;
1915
import com.google.firebase.auth.FirebaseAuth;
2016
import com.google.firebase.auth.FirebaseUser;
2117

@@ -46,7 +42,7 @@ protected static Intent createBaseIntent(
4642
@Override
4743
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
4844
super.onActivityResult(requestCode, resultCode, data);
49-
// Forward the results of Smart Lock saving
45+
// Forward the results of CredentialManager saving
5046
if (requestCode == RequestCodes.CRED_SAVE_FLOW
5147
|| resultCode == ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
5248
finish(resultCode, data);
@@ -73,18 +69,29 @@ public void finish(int resultCode, @Nullable Intent intent) {
7369
finish();
7470
}
7571

72+
/**
73+
* Starts the CredentialManager save flow.
74+
*
75+
* <p>Instead of building a SmartLock {@link com.google.android.gms.auth.api.credentials.Credential},
76+
* we now extract the user's email (or phone number as a fallback) and pass it along with the
77+
* password and response.</p>
78+
*
79+
* @param firebaseUser the currently signed-in user.
80+
* @param response the IdP response.
81+
* @param password the password used during sign-in (may be {@code null}).
82+
*/
7683
public void startSaveCredentials(
7784
FirebaseUser firebaseUser,
7885
IdpResponse response,
7986
@Nullable String password) {
80-
// Build credential
81-
String accountType = ProviderUtils.idpResponseToAccountType(response);
82-
Credential credential = CredentialUtils.buildCredential(
83-
firebaseUser, password, accountType);
84-
85-
// Start the dedicated SmartLock Activity
87+
// Extract email; if null, fallback to the phone number.
88+
String email = firebaseUser.getEmail();
89+
if (email == null) {
90+
email = firebaseUser.getPhoneNumber();
91+
}
92+
// Start the dedicated CredentialManager Activity.
8693
Intent intent = CredentialSaveActivity.createIntent(
87-
this, getFlowParams(), credential, response);
94+
this, getFlowParams(), email, password, response);
8895
startActivityForResult(intent, RequestCodes.CRED_SAVE_FLOW);
8996
}
9097

@@ -101,4 +108,4 @@ protected boolean isOffline() {
101108
&& manager.getActiveNetworkInfo() != null
102109
&& manager.getActiveNetworkInfo().isConnectedOrConnecting());
103110
}
104-
}
111+
}

auth/src/main/java/com/firebase/ui/auth/ui/credentials/CredentialSaveActivity.kt

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,45 @@ import android.content.Context
44
import android.content.Intent
55
import android.os.Bundle
66
import android.util.Log
7+
import androidx.lifecycle.ViewModelProvider
78
import com.firebase.ui.auth.IdpResponse
89
import com.firebase.ui.auth.data.model.FlowParameters
910
import com.firebase.ui.auth.data.model.Resource
1011
import com.firebase.ui.auth.ui.InvisibleActivityBase
1112
import com.firebase.ui.auth.util.ExtraConstants
1213
import com.firebase.ui.auth.viewmodel.ResourceObserver
1314
import com.firebase.ui.auth.viewmodel.credentialmanager.CredentialManagerHandler
14-
import com.google.android.gms.auth.api.credentials.Credential
15-
import androidx.lifecycle.ViewModelProvider
1615
import com.google.firebase.auth.FirebaseAuth
1716

1817
class CredentialSaveActivity : InvisibleActivityBase() {
1918

20-
21-
2219
private lateinit var credentialManagerHandler: CredentialManagerHandler
2320

2421
override fun onCreate(savedInstanceState: Bundle?) {
2522
super.onCreate(savedInstanceState)
2623

2724
val response: IdpResponse? = intent.getParcelableExtra(ExtraConstants.IDP_RESPONSE)
28-
val credential: Credential? = intent.getParcelableExtra(ExtraConstants.CREDENTIAL)
25+
val emailExtra: String? = intent.getStringExtra(ExtraConstants.EMAIL)
26+
val password: String? = intent.getStringExtra(ExtraConstants.PASSWORD)
2927

3028
credentialManagerHandler = ViewModelProvider(this)
3129
.get(CredentialManagerHandler::class.java)
3230
.apply {
33-
// Initialize with flow parameters
31+
// Initialize with flow parameters.
3432
init(flowParams)
35-
// If we have an IdpResponse, set it so subsequent operations can report results
33+
// Pass the IdP response if present.
3634
response?.let { setResponse(it) }
3735

38-
// Observe the operation resource
36+
// Observe the operation's result.
3937
operation.observe(
4038
this@CredentialSaveActivity,
4139
object : ResourceObserver<IdpResponse>(this@CredentialSaveActivity) {
4240
override fun onSuccess(response: IdpResponse) {
43-
// Done saving – success
4441
finish(RESULT_OK, response.toIntent())
4542
}
4643

4744
override fun onFailure(e: Exception) {
48-
// We don’t want to block the sign-in flow just because saving failed,
49-
// so return RESULT_OK
45+
// Even if saving fails, do not block the sign-in flow.
5046
response?.let {
5147
finish(RESULT_OK, it.toIntent())
5248
} ?: finish(RESULT_OK, null)
@@ -59,14 +55,11 @@ class CredentialSaveActivity : InvisibleActivityBase() {
5955

6056
if (currentOp == null) {
6157
Log.d(TAG, "Launching save operation.")
62-
// In the old SmartLock flow, you saved a `Credential`;
63-
// with CredentialManager, we typically need email & password for the new request.
64-
// Example usage: pass the current user & the password.
65-
// Adjust as needed for passkeys or other flows.
58+
// With the new CredentialManager, pass the email and password directly.
6659
val firebaseUser = FirebaseAuth.getInstance().currentUser
67-
val password = credential?.password
60+
val email = firebaseUser?.email ?: emailExtra
6861

69-
credentialManagerHandler.saveCredentials(this, firebaseUser, password)
62+
credentialManagerHandler.saveCredentials(this, firebaseUser, email, password)
7063
} else {
7164
Log.d(TAG, "Save operation in progress, doing nothing.")
7265
}
@@ -79,11 +72,13 @@ class CredentialSaveActivity : InvisibleActivityBase() {
7972
fun createIntent(
8073
context: Context,
8174
flowParams: FlowParameters,
82-
credential: Credential,
75+
email: String,
76+
password: String,
8377
response: IdpResponse
8478
): Intent {
8579
return createBaseIntent(context, CredentialSaveActivity::class.java, flowParams).apply {
86-
putExtra(ExtraConstants.CREDENTIAL, credential)
80+
putExtra(ExtraConstants.EMAIL, email)
81+
putExtra(ExtraConstants.PASSWORD, password)
8782
putExtra(ExtraConstants.IDP_RESPONSE, response)
8883
}
8984
}

auth/src/main/java/com/firebase/ui/auth/ui/email/EmailLinkPromptEmailFragment.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class EmailLinkPromptEmailFragment extends FragmentBase implements
3232
public static final String TAG = "EmailLinkPromptEmailFragment";
3333

3434
private Button mNextButton;
35+
private Button mSignUpButton;
3536
private ProgressBar mProgressBar;
3637

3738
private EditText mEmailEditText;

auth/src/main/java/com/firebase/ui/auth/ui/phone/CheckPhoneHandler.java

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,90 @@
33
import android.app.Activity;
44
import android.app.Application;
55
import android.content.Intent;
6+
import android.content.IntentSender;
7+
import android.util.Log;
68

79
import com.firebase.ui.auth.data.model.PendingIntentRequiredException;
810
import com.firebase.ui.auth.data.model.PhoneNumber;
911
import com.firebase.ui.auth.data.model.Resource;
1012
import com.firebase.ui.auth.util.data.PhoneNumberUtils;
1113
import com.firebase.ui.auth.viewmodel.AuthViewModelBase;
1214
import com.firebase.ui.auth.viewmodel.RequestCodes;
13-
import com.google.android.gms.auth.api.credentials.Credential;
14-
import com.google.android.gms.auth.api.credentials.Credentials;
15-
import com.google.android.gms.auth.api.credentials.HintRequest;
15+
import com.google.android.gms.auth.api.identity.GetPhoneNumberHintIntentRequest;
16+
import com.google.android.gms.auth.api.identity.Identity;
1617

1718
import androidx.annotation.Nullable;
1819
import androidx.annotation.RestrictTo;
1920

2021
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
2122
public class CheckPhoneHandler extends AuthViewModelBase<PhoneNumber> {
23+
24+
private static final String TAG = "CheckPhoneHandler";
25+
2226
public CheckPhoneHandler(Application application) {
2327
super(application);
2428
}
2529

26-
public void fetchCredential() {
27-
setResult(Resource.forFailure(new PendingIntentRequiredException(
28-
Credentials.getClient(getApplication()).getHintPickerIntent(
29-
new HintRequest.Builder().setPhoneNumberIdentifierSupported(true).build()),
30-
RequestCodes.CRED_HINT
31-
)));
30+
/**
31+
* Initiates the Phone Number Hint flow using the new API.
32+
*
33+
* <p>This method creates a GetPhoneNumberHintIntentRequest and calls
34+
* Identity.getSignInClient(activity).getPhoneNumberHintIntent(request) to retrieve an
35+
* IntentSender. The IntentSender is then wrapped in a PendingIntentRequiredException so that
36+
* the caller can launch the hint flow.
37+
*
38+
* <p><strong>Note:</strong> Update your PendingIntentRequiredException to accept an IntentSender
39+
* rather than a PendingIntent.
40+
*
41+
* @param activity The activity used to retrieve the Phone Number Hint IntentSender.
42+
*/
43+
public void fetchCredential(final Activity activity) {
44+
GetPhoneNumberHintIntentRequest request = GetPhoneNumberHintIntentRequest.builder().build();
45+
Identity.getSignInClient(activity)
46+
.getPhoneNumberHintIntent(request)
47+
.addOnSuccessListener(result -> {
48+
try {
49+
// The new API returns an IntentSender.
50+
IntentSender intentSender = result.getIntentSender();
51+
// Update your exception to accept an IntentSender.
52+
setResult(Resource.forFailure(new PendingIntentRequiredException(intentSender, RequestCodes.CRED_HINT)));
53+
} catch (Exception e) {
54+
Log.e(TAG, "Launching the IntentSender failed", e);
55+
setResult(Resource.forFailure(e));
56+
}
57+
})
58+
.addOnFailureListener(e -> {
59+
Log.e(TAG, "Phone Number Hint failed", e);
60+
setResult(Resource.forFailure(e));
61+
});
3262
}
3363

34-
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
35-
if (requestCode != RequestCodes.CRED_HINT || resultCode != Activity.RESULT_OK) { return; }
36-
37-
Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
38-
String formattedPhone = PhoneNumberUtils.formatUsingCurrentCountry(
39-
credential.getId(), getApplication());
40-
if (formattedPhone != null) {
41-
setResult(Resource.forSuccess(PhoneNumberUtils.getPhoneNumber(formattedPhone)));
64+
/**
65+
* Handles the result from the Phone Number Hint flow.
66+
*
67+
* <p>Call this method from your Activity's onActivityResult. It extracts the phone number from the
68+
* returned Intent and formats it.
69+
*
70+
* @param activity The activity used to process the returned Intent.
71+
* @param requestCode The request code (should match RequestCodes.CRED_HINT).
72+
* @param resultCode The result code from the hint flow.
73+
* @param data The Intent data returned from the hint flow.
74+
*/
75+
public void onActivityResult(Activity activity, int requestCode, int resultCode, @Nullable Intent data) {
76+
if (requestCode != RequestCodes.CRED_HINT || resultCode != Activity.RESULT_OK) {
77+
return;
78+
}
79+
try {
80+
String phoneNumber = Identity.getSignInClient(activity).getPhoneNumberFromIntent(data);
81+
String formattedPhone = PhoneNumberUtils.formatUsingCurrentCountry(phoneNumber, getApplication());
82+
if (formattedPhone != null) {
83+
setResult(Resource.forSuccess(PhoneNumberUtils.getPhoneNumber(formattedPhone)));
84+
} else {
85+
setResult(Resource.forFailure(new Exception("Failed to format phone number")));
86+
}
87+
} catch (Exception e) {
88+
Log.e(TAG, "Phone Number Hint failed", e);
89+
setResult(Resource.forFailure(e));
4290
}
4391
}
44-
}
92+
}

0 commit comments

Comments
 (0)