Skip to content

Commit 798957f

Browse files
authored
Use ActivityResultLauncher in FirebaseUI Auth Snippets (#303)
1 parent 621ee48 commit 798957f

File tree

3 files changed

+184
-84
lines changed

3 files changed

+184
-84
lines changed

auth/app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ dependencies {
2828
implementation 'androidx.cardview:cardview:1.0.0'
2929
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
3030
implementation 'com.google.android.material:material:1.3.0'
31+
implementation 'androidx.activity:activity:1.2.3'
3132

3233
implementation "com.google.firebase:firebase-auth-ktx:21.0.1"
3334

auth/app/src/main/java/com/google/firebase/quickstart/auth/FirebaseUIActivity.java

Lines changed: 96 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@
22

33
import android.content.Intent;
44
import android.os.Bundle;
5+
6+
import androidx.activity.result.ActivityResultCallback;
7+
import androidx.activity.result.ActivityResultLauncher;
58
import androidx.annotation.NonNull;
69
import androidx.appcompat.app.AppCompatActivity;
710

811
import com.firebase.ui.auth.AuthUI;
12+
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
913
import com.firebase.ui.auth.IdpResponse;
14+
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
15+
import com.firebase.ui.auth.util.ExtraConstants;
1016
import com.google.android.gms.tasks.OnCompleteListener;
1117
import com.google.android.gms.tasks.Task;
18+
import com.google.firebase.auth.ActionCodeSettings;
1219
import com.google.firebase.auth.FirebaseAuth;
1320
import com.google.firebase.auth.FirebaseUser;
1421

@@ -18,7 +25,18 @@
1825

1926
public class FirebaseUIActivity extends AppCompatActivity {
2027

21-
private static final int RC_SIGN_IN = 123;
28+
// [START auth_fui_create_launcher]
29+
// See: https://developer.android.com/training/basics/intents/result
30+
private final ActivityResultLauncher<Intent> signInLauncher = registerForActivityResult(
31+
new FirebaseAuthUIActivityResultContract(),
32+
new ActivityResultCallback<FirebaseAuthUIAuthenticationResult>() {
33+
@Override
34+
public void onActivityResult(FirebaseAuthUIAuthenticationResult result) {
35+
onSignInResult(result);
36+
}
37+
}
38+
);
39+
// [END auth_fui_create_launcher]
2240

2341
@Override
2442
protected void onCreate(Bundle savedInstanceState) {
@@ -37,33 +55,26 @@ public void createSignInIntent() {
3755
new AuthUI.IdpConfig.TwitterBuilder().build());
3856

3957
// Create and launch sign-in intent
40-
startActivityForResult(
41-
AuthUI.getInstance()
42-
.createSignInIntentBuilder()
43-
.setAvailableProviders(providers)
44-
.build(),
45-
RC_SIGN_IN);
58+
Intent signInIntent = AuthUI.getInstance()
59+
.createSignInIntentBuilder()
60+
.setAvailableProviders(providers)
61+
.build();
62+
signInLauncher.launch(signInIntent);
4663
// [END auth_fui_create_intent]
4764
}
4865

4966
// [START auth_fui_result]
50-
@Override
51-
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
52-
super.onActivityResult(requestCode, resultCode, data);
53-
54-
if (requestCode == RC_SIGN_IN) {
55-
IdpResponse response = IdpResponse.fromResultIntent(data);
56-
57-
if (resultCode == RESULT_OK) {
58-
// Successfully signed in
59-
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
60-
// ...
61-
} else {
62-
// Sign in failed. If response is null the user canceled the
63-
// sign-in flow using the back button. Otherwise check
64-
// response.getError().getErrorCode() and handle the error.
65-
// ...
66-
}
67+
private void onSignInResult(FirebaseAuthUIAuthenticationResult result) {
68+
IdpResponse response = result.getIdpResponse();
69+
if (result.getResultCode() == RESULT_OK) {
70+
// Successfully signed in
71+
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
72+
// ...
73+
} else {
74+
// Sign in failed. If response is null the user canceled the
75+
// sign-in flow using the back button. Otherwise check
76+
// response.getError().getErrorCode() and handle the error.
77+
// ...
6778
}
6879
}
6980
// [END auth_fui_result]
@@ -97,29 +108,74 @@ public void themeAndLogo() {
97108
List<AuthUI.IdpConfig> providers = Collections.emptyList();
98109

99110
// [START auth_fui_theme_logo]
100-
startActivityForResult(
101-
AuthUI.getInstance()
102-
.createSignInIntentBuilder()
103-
.setAvailableProviders(providers)
104-
.setLogo(R.drawable.my_great_logo) // Set logo drawable
105-
.setTheme(R.style.MySuperAppTheme) // Set theme
106-
.build(),
107-
RC_SIGN_IN);
111+
Intent signInIntent = AuthUI.getInstance()
112+
.createSignInIntentBuilder()
113+
.setAvailableProviders(providers)
114+
.setLogo(R.drawable.my_great_logo) // Set logo drawable
115+
.setTheme(R.style.MySuperAppTheme) // Set theme
116+
.build();
117+
signInLauncher.launch(signInIntent);
108118
// [END auth_fui_theme_logo]
109119
}
110120

111121
public void privacyAndTerms() {
112122
List<AuthUI.IdpConfig> providers = Collections.emptyList();
123+
113124
// [START auth_fui_pp_tos]
114-
startActivityForResult(
115-
AuthUI.getInstance()
125+
Intent signInIntent = AuthUI.getInstance()
126+
.createSignInIntentBuilder()
127+
.setAvailableProviders(providers)
128+
.setTosAndPrivacyPolicyUrls(
129+
"https://example.com/terms.html",
130+
"https://example.com/privacy.html")
131+
.build();
132+
signInLauncher.launch(signInIntent);
133+
// [END auth_fui_pp_tos]
134+
}
135+
136+
public void emailLink() {
137+
// [START auth_fui_email_link]
138+
ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder()
139+
.setAndroidPackageName(
140+
/* yourPackageName= */ "...",
141+
/* installIfNotAvailable= */ true,
142+
/* minimumVersion= */ null)
143+
.setHandleCodeInApp(true) // This must be set to true
144+
.setUrl("https://google.com") // This URL needs to be whitelisted
145+
.build();
146+
147+
List<AuthUI.IdpConfig> providers = Arrays.asList(
148+
new AuthUI.IdpConfig.EmailBuilder()
149+
.enableEmailLinkSignIn()
150+
.setActionCodeSettings(actionCodeSettings)
151+
.build()
152+
);
153+
Intent signInIntent = AuthUI.getInstance()
154+
.createSignInIntentBuilder()
155+
.setAvailableProviders(providers)
156+
.build();
157+
signInLauncher.launch(signInIntent);
158+
// [END auth_fui_email_link]
159+
}
160+
161+
public void catchEmailLink() {
162+
List<AuthUI.IdpConfig> providers = Collections.emptyList();
163+
164+
// [START auth_fui_email_link_catch]
165+
if (AuthUI.canHandleIntent(getIntent())) {
166+
if (getIntent().getExtras() == null) {
167+
return;
168+
}
169+
String link = getIntent().getExtras().getString(ExtraConstants.EMAIL_LINK_SIGN_IN);
170+
if (link != null) {
171+
Intent signInIntent = AuthUI.getInstance()
116172
.createSignInIntentBuilder()
173+
.setEmailLink(link)
117174
.setAvailableProviders(providers)
118-
.setTosAndPrivacyPolicyUrls(
119-
"https://example.com/terms.html",
120-
"https://example.com/privacy.html")
121-
.build(),
122-
RC_SIGN_IN);
123-
// [END auth_fui_pp_tos]
175+
.build();
176+
signInLauncher.launch(signInIntent);
177+
}
178+
}
179+
// [END auth_fui_email_link_catch]
124180
}
125181
}
Lines changed: 87 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
package com.google.firebase.quickstart.auth.kotlin
22

3-
import android.app.Activity
4-
import android.content.Intent
53
import android.os.Bundle
64
import androidx.appcompat.app.AppCompatActivity
75
import com.firebase.ui.auth.AuthUI
8-
import com.firebase.ui.auth.IdpResponse
6+
import com.firebase.ui.auth.AuthUI.IdpConfig
7+
import com.firebase.ui.auth.AuthUI.IdpConfig.EmailBuilder
8+
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract
9+
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult
10+
import com.firebase.ui.auth.util.ExtraConstants
11+
import com.google.firebase.auth.ActionCodeSettings
912
import com.google.firebase.auth.FirebaseAuth
1013
import com.google.firebase.quickstart.auth.R
1114

1215
abstract class FirebaseUIActivity : AppCompatActivity() {
1316

17+
// [START auth_fui_create_launcher]
18+
// See: https://developer.android.com/training/basics/intents/result
19+
private val signInLauncher = registerForActivityResult(
20+
FirebaseAuthUIActivityResultContract()
21+
) { res ->
22+
this.onSignInResult(res)
23+
}
24+
// [END auth_fui_create_launcher]
25+
1426
override fun onCreate(savedInstanceState: Bundle?) {
1527
super.onCreate(savedInstanceState)
1628
setContentView(R.layout.activity_firebase_ui)
@@ -27,32 +39,26 @@ abstract class FirebaseUIActivity : AppCompatActivity() {
2739
AuthUI.IdpConfig.TwitterBuilder().build())
2840

2941
// Create and launch sign-in intent
30-
startActivityForResult(
31-
AuthUI.getInstance()
32-
.createSignInIntentBuilder()
33-
.setAvailableProviders(providers)
34-
.build(),
35-
RC_SIGN_IN)
42+
val signInIntent = AuthUI.getInstance()
43+
.createSignInIntentBuilder()
44+
.setAvailableProviders(providers)
45+
.build()
46+
signInLauncher.launch(signInIntent)
3647
// [END auth_fui_create_intent]
3748
}
3849

3950
// [START auth_fui_result]
40-
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
41-
super.onActivityResult(requestCode, resultCode, data)
42-
43-
if (requestCode == RC_SIGN_IN) {
44-
val response = IdpResponse.fromResultIntent(data)
45-
46-
if (resultCode == Activity.RESULT_OK) {
47-
// Successfully signed in
48-
val user = FirebaseAuth.getInstance().currentUser
49-
// ...
50-
} else {
51-
// Sign in failed. If response is null the user canceled the
52-
// sign-in flow using the back button. Otherwise check
53-
// response.getError().getErrorCode() and handle the error.
54-
// ...
55-
}
51+
private fun onSignInResult(result: FirebaseAuthUIAuthenticationResult) {
52+
val response = result.idpResponse
53+
if (result.resultCode == RESULT_OK) {
54+
// Successfully signed in
55+
val user = FirebaseAuth.getInstance().currentUser
56+
// ...
57+
} else {
58+
// Sign in failed. If response is null the user canceled the
59+
// sign-in flow using the back button. Otherwise check
60+
// response.getError().getErrorCode() and handle the error.
61+
// ...
5662
}
5763
}
5864
// [END auth_fui_result]
@@ -81,34 +87,71 @@ abstract class FirebaseUIActivity : AppCompatActivity() {
8187
val providers = emptyList<AuthUI.IdpConfig>()
8288

8389
// [START auth_fui_theme_logo]
84-
startActivityForResult(
85-
AuthUI.getInstance()
86-
.createSignInIntentBuilder()
87-
.setAvailableProviders(providers)
88-
.setLogo(R.drawable.my_great_logo) // Set logo drawable
89-
.setTheme(R.style.MySuperAppTheme) // Set theme
90-
.build(),
91-
RC_SIGN_IN)
90+
val signInIntent = AuthUI.getInstance()
91+
.createSignInIntentBuilder()
92+
.setAvailableProviders(providers)
93+
.setLogo(R.drawable.my_great_logo) // Set logo drawable
94+
.setTheme(R.style.MySuperAppTheme) // Set theme
95+
.build()
96+
signInLauncher.launch(signInIntent)
9297
// [END auth_fui_theme_logo]
9398
}
9499

95100
private fun privacyAndTerms() {
96101
val providers = emptyList<AuthUI.IdpConfig>()
97102
// [START auth_fui_pp_tos]
98-
startActivityForResult(
99-
AuthUI.getInstance()
100-
.createSignInIntentBuilder()
101-
.setAvailableProviders(providers)
102-
.setTosAndPrivacyPolicyUrls(
103-
"https://example.com/terms.html",
104-
"https://example.com/privacy.html")
105-
.build(),
106-
RC_SIGN_IN)
103+
val signInIntent = AuthUI.getInstance()
104+
.createSignInIntentBuilder()
105+
.setAvailableProviders(providers)
106+
.setTosAndPrivacyPolicyUrls(
107+
"https://example.com/terms.html",
108+
"https://example.com/privacy.html")
109+
.build()
110+
signInLauncher.launch(signInIntent)
107111
// [END auth_fui_pp_tos]
108112
}
109113

110-
companion object {
114+
open fun emailLink() {
115+
// [START auth_fui_email_link]
116+
val actionCodeSettings = ActionCodeSettings.newBuilder()
117+
.setAndroidPackageName( /* yourPackageName= */
118+
"...", /* installIfNotAvailable= */
119+
true, /* minimumVersion= */
120+
null)
121+
.setHandleCodeInApp(true) // This must be set to true
122+
.setUrl("https://google.com") // This URL needs to be whitelisted
123+
.build()
124+
125+
val providers = listOf(
126+
EmailBuilder()
127+
.enableEmailLinkSignIn()
128+
.setActionCodeSettings(actionCodeSettings)
129+
.build()
130+
)
131+
val signInIntent = AuthUI.getInstance()
132+
.createSignInIntentBuilder()
133+
.setAvailableProviders(providers)
134+
.build()
135+
signInLauncher.launch(signInIntent)
136+
// [END auth_fui_email_link]
137+
}
138+
139+
open fun catchEmailLink() {
140+
val providers: List<IdpConfig> = emptyList()
111141

112-
private const val RC_SIGN_IN = 123
142+
// [START auth_fui_email_link_catch]
143+
if (AuthUI.canHandleIntent(intent)) {
144+
val extras = intent.extras ?: return
145+
val link = extras.getString(ExtraConstants.EMAIL_LINK_SIGN_IN)
146+
if (link != null) {
147+
val signInIntent = AuthUI.getInstance()
148+
.createSignInIntentBuilder()
149+
.setEmailLink(link)
150+
.setAvailableProviders(providers)
151+
.build()
152+
signInLauncher.launch(signInIntent)
153+
}
154+
}
155+
// [END auth_fui_email_link_catch]
113156
}
114157
}

0 commit comments

Comments
 (0)