Skip to content

Commit 706d539

Browse files
committed
Add support for Firebase backed silent sign-in
Signed-off-by: Alex Saveau <[email protected]>
1 parent ec6b88b commit 706d539

File tree

4 files changed

+117
-3
lines changed

4 files changed

+117
-3
lines changed

app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
import android.content.Intent;
1919
import android.os.Bundle;
2020
import android.support.annotation.DrawableRes;
21+
import android.support.annotation.NonNull;
2122
import android.support.annotation.StringRes;
2223
import android.support.annotation.StyleRes;
2324
import android.support.design.widget.Snackbar;
2425
import android.support.v7.app.AppCompatActivity;
2526
import android.support.v7.app.AppCompatDelegate;
2627
import android.util.Log;
2728
import android.view.View;
28-
import android.widget.Button;
2929
import android.widget.CheckBox;
3030
import android.widget.CompoundButton;
3131
import android.widget.CompoundButton.OnCheckedChangeListener;
@@ -38,7 +38,12 @@
3838
import com.firebase.ui.auth.IdpResponse;
3939
import com.firebase.uidemo.R;
4040
import com.google.android.gms.common.Scopes;
41+
import com.google.android.gms.tasks.OnCompleteListener;
42+
import com.google.android.gms.tasks.Task;
43+
import com.google.firebase.auth.AuthResult;
44+
import com.google.firebase.auth.EmailAuthProvider;
4145
import com.google.firebase.auth.FirebaseAuth;
46+
import com.google.firebase.auth.GoogleAuthProvider;
4247

4348
import java.util.ArrayList;
4449
import java.util.Arrays;
@@ -59,7 +64,6 @@ public class AuthUiActivity extends AppCompatActivity {
5964
private static final int RC_SIGN_IN = 100;
6065

6166
@BindView(R.id.root) View mRootView;
62-
@BindView(R.id.sign_in) Button mSignIn;
6367

6468
@BindView(R.id.google_provider) CheckBox mUseGoogleProvider;
6569
@BindView(R.id.facebook_provider) CheckBox mUseFacebookProvider;
@@ -165,6 +169,31 @@ public void signIn(View view) {
165169
RC_SIGN_IN);
166170
}
167171

172+
@OnClick(R.id.sign_in_silent)
173+
public void silentSignIn(View view) {
174+
List<IdpConfig> providers = new ArrayList<>();
175+
List<IdpConfig> selected = getSelectedProviders();
176+
for (IdpConfig config : selected) {
177+
String provider = config.getProviderId();
178+
if (provider.equals(EmailAuthProvider.PROVIDER_ID)
179+
|| provider.equals(GoogleAuthProvider.PROVIDER_ID)) {
180+
providers.add(config);
181+
}
182+
}
183+
184+
AuthUI.getInstance().silentSignIn(this, providers)
185+
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
186+
@Override
187+
public void onComplete(@NonNull Task<AuthResult> task) {
188+
if (task.isSuccessful()) {
189+
startSignedInActivity(null);
190+
} else {
191+
showSnackbar(R.string.sign_in_failed);
192+
}
193+
}
194+
});
195+
}
196+
168197
@Override
169198
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
170199
super.onActivityResult(requestCode, resultCode, data);

app/src/main/res/layout/auth_ui_layout.xml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,18 @@
3535
android:layout_width="wrap_content"
3636
android:layout_height="wrap_content"
3737
android:layout_gravity="center"
38-
android:layout_margin="16dp"
38+
android:layout_marginTop="16dp"
3939
android:text="@string/sign_in_start" />
4040

41+
<Button
42+
android:id="@+id/sign_in_silent"
43+
style="@style/Widget.AppCompat.Button.Colored"
44+
android:layout_width="wrap_content"
45+
android:layout_height="wrap_content"
46+
android:layout_gravity="center"
47+
android:layout_marginBottom="16dp"
48+
android:text="@string/sign_in_silent" />
49+
4150
<TextView
4251
style="@style/Base.TextAppearance.AppCompat.Subhead"
4352
android:layout_width="wrap_content"

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<!-- Auth UI -->
1616
<string name="launch_title">FirebaseUI Auth Demo</string>
1717
<string name="sign_in_start">Start</string>
18+
<string name="sign_in_silent">Sign in silently</string>
1819

1920
<string name="providers_header">Auth providers</string>
2021
<string name="providers_google">Google</string>
@@ -70,6 +71,7 @@
7071
<string name="sign_out">Sign out</string>
7172
<string name="delete_account_label">Delete account</string>
7273

74+
<string name="sign_in_failed">Sign in failed</string>
7375
<string name="sign_out_failed">Sign out failed</string>
7476
<string name="delete_account_failed">Delete account failed</string>
7577

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

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@
4040
import com.firebase.ui.auth.util.data.PhoneNumberUtils;
4141
import com.firebase.ui.auth.util.data.ProviderUtils;
4242
import com.google.android.gms.auth.api.credentials.Credential;
43+
import com.google.android.gms.auth.api.credentials.CredentialRequest;
44+
import com.google.android.gms.auth.api.credentials.CredentialRequestResponse;
4345
import com.google.android.gms.auth.api.credentials.CredentialsClient;
4446
import com.google.android.gms.auth.api.signin.GoogleSignIn;
47+
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
4548
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
4649
import com.google.android.gms.common.api.ApiException;
4750
import com.google.android.gms.common.api.CommonStatusCodes;
@@ -50,6 +53,8 @@
5053
import com.google.android.gms.tasks.Task;
5154
import com.google.android.gms.tasks.Tasks;
5255
import com.google.firebase.FirebaseApp;
56+
import com.google.firebase.auth.AuthCredential;
57+
import com.google.firebase.auth.AuthResult;
5358
import com.google.firebase.auth.EmailAuthProvider;
5459
import com.google.firebase.auth.FacebookAuthProvider;
5560
import com.google.firebase.auth.FirebaseAuth;
@@ -262,6 +267,75 @@ public static int getDefaultTheme() {
262267
return R.style.FirebaseUI;
263268
}
264269

270+
public Task<AuthResult> silentSignIn(@NonNull final Context context, List<IdpConfig> configs) {
271+
if (configs.isEmpty()) {
272+
throw new IllegalArgumentException("Configs must not be empty.");
273+
}
274+
for (IdpConfig config : configs) {
275+
String provider = config.getProviderId();
276+
if (!provider.equals(EmailAuthProvider.PROVIDER_ID)
277+
&& !provider.equals(GoogleAuthProvider.PROVIDER_ID)) {
278+
throw new IllegalArgumentException("Only email and google providers are supported " +
279+
"for silent sign-in.");
280+
}
281+
}
282+
283+
if (mAuth.getCurrentUser() != null) {
284+
return Tasks.forException(new IllegalStateException("User already signed in!"));
285+
}
286+
287+
final IdpConfig google =
288+
ProviderUtils.getConfigFromIdps(configs, GoogleAuthProvider.PROVIDER_ID);
289+
final IdpConfig email =
290+
ProviderUtils.getConfigFromIdps(configs, EmailAuthProvider.PROVIDER_ID);
291+
292+
GoogleSignInOptions googleOptions = null;
293+
if (google != null) {
294+
GoogleSignInAccount last = GoogleSignIn.getLastSignedInAccount(context);
295+
if (last != null && last.getIdToken() != null) {
296+
return mAuth.signInWithCredential(GoogleAuthProvider.getCredential(
297+
last.getIdToken(), null));
298+
}
299+
300+
googleOptions = google.getParams()
301+
.getParcelable(ExtraConstants.EXTRA_GOOGLE_SIGN_IN_OPTIONS);
302+
}
303+
304+
final GoogleSignInOptions finalGoogleOptions = googleOptions;
305+
return GoogleApiUtils.getCredentialsClient(context)
306+
.request(new CredentialRequest.Builder()
307+
.setPasswordLoginSupported(email != null)
308+
.setAccountTypes(google == null ? null :
309+
ProviderUtils.providerIdToAccountType(GoogleAuthProvider.PROVIDER_ID))
310+
.build())
311+
.continueWithTask(new Continuation<CredentialRequestResponse, Task<AuthResult>>() {
312+
@Override
313+
public Task<AuthResult> then(@NonNull Task<CredentialRequestResponse> task) {
314+
Credential credential = task.getResult().getCredential();
315+
String email = credential.getId();
316+
String password = credential.getPassword();
317+
318+
if (TextUtils.isEmpty(password)) {
319+
return GoogleSignIn.getClient(context,
320+
new GoogleSignInOptions.Builder(finalGoogleOptions)
321+
.setAccountName(email)
322+
.build())
323+
.silentSignIn()
324+
.continueWithTask(new Continuation<GoogleSignInAccount, Task<AuthResult>>() {
325+
@Override
326+
public Task<AuthResult> then(@NonNull Task<GoogleSignInAccount> task) {
327+
AuthCredential authCredential = GoogleAuthProvider.getCredential(
328+
task.getResult().getIdToken(), null);
329+
return mAuth.signInWithCredential(authCredential);
330+
}
331+
});
332+
} else {
333+
return mAuth.signInWithEmailAndPassword(email, password);
334+
}
335+
}
336+
});
337+
}
338+
265339
/**
266340
* Signs the current user out, if one is signed in.
267341
*

0 commit comments

Comments
 (0)