Skip to content

Commit 068899c

Browse files
authored
Return tokens on successful sign in with an IDP (#362)
This exposes the IdpResponse object to the user. It can be retrieved from the result intent received in onActivityResult using IdpResponse.fromResultIntent(data). Resolves #286.
1 parent 897b455 commit 068899c

32 files changed

+371
-261
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import android.widget.TextView;
3434
import com.firebase.ui.auth.AuthUI;
3535
import com.firebase.ui.auth.AuthUI.IdpConfig;
36+
import com.firebase.ui.auth.IdpResponse;
3637
import com.firebase.ui.auth.ui.ResultCodes;
3738
import com.firebase.uidemo.R;
3839
import com.google.android.gms.common.Scopes;
@@ -128,7 +129,7 @@ public void onCreate(Bundle savedInstanceState) {
128129

129130
FirebaseAuth auth = FirebaseAuth.getInstance();
130131
if (auth.getCurrentUser() != null) {
131-
startActivity(SignedInActivity.createIntent(this));
132+
startActivity(SignedInActivity.createIntent(this, null));
132133
finish();
133134
}
134135

@@ -219,7 +220,7 @@ private void setFacebookScopesEnabled(boolean enabled) {
219220
@MainThread
220221
private void handleSignInResponse(int resultCode, Intent data) {
221222
if (resultCode == RESULT_OK) {
222-
startActivity(SignedInActivity.createIntent(this));
223+
startActivity(SignedInActivity.createIntent(this, IdpResponse.fromResultIntent(data)));
223224
finish();
224225
return;
225226
}

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

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@
2828
import android.view.View;
2929
import android.widget.ImageView;
3030
import android.widget.TextView;
31-
31+
import butterknife.BindView;
32+
import butterknife.ButterKnife;
33+
import butterknife.OnClick;
3234
import com.bumptech.glide.Glide;
3335
import com.firebase.ui.auth.AuthUI;
36+
import com.firebase.ui.auth.IdpResponse;
3437
import com.firebase.uidemo.R;
3538
import com.google.android.gms.tasks.OnCompleteListener;
3639
import com.google.android.gms.tasks.Task;
@@ -39,14 +42,10 @@
3942
import com.google.firebase.auth.FirebaseAuth;
4043
import com.google.firebase.auth.FirebaseUser;
4144
import com.google.firebase.auth.GoogleAuthProvider;
42-
4345
import java.util.Iterator;
4446

45-
import butterknife.BindView;
46-
import butterknife.ButterKnife;
47-
import butterknife.OnClick;
48-
4947
public class SignedInActivity extends AppCompatActivity {
48+
private static final String EXTRA_IDP_RESPONSE = "extra_idp_response";
5049

5150
@BindView(android.R.id.content)
5251
View mRootView;
@@ -77,6 +76,7 @@ public void onCreate(Bundle savedInstanceState) {
7776
setContentView(R.layout.signed_in_layout);
7877
ButterKnife.bind(this);
7978
populateProfile();
79+
populateIdpToken();
8080
}
8181

8282
@OnClick(R.id.sign_out)
@@ -173,15 +173,34 @@ private void populateProfile() {
173173
mEnabledProviders.setText(providerList);
174174
}
175175

176+
private void populateIdpToken() {
177+
IdpResponse idpResponse = getIntent().getParcelableExtra(EXTRA_IDP_RESPONSE);
178+
if (idpResponse != null) {
179+
String token = idpResponse.getIdpToken();
180+
String secret = idpResponse.getIdpSecret();
181+
if (token == null) {
182+
findViewById(R.id.idp_token_layout).setVisibility(View.GONE);
183+
} else {
184+
((TextView) findViewById(R.id.idp_token)).setText(token);
185+
}
186+
if (secret == null) {
187+
findViewById(R.id.idp_secret_layout).setVisibility(View.GONE);
188+
} else {
189+
((TextView) findViewById(R.id.idp_secret)).setText(secret);
190+
}
191+
}
192+
}
193+
176194
@MainThread
177195
private void showSnackbar(@StringRes int errorMessageRes) {
178196
Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG)
179197
.show();
180198
}
181199

182-
public static Intent createIntent(Context context) {
200+
public static Intent createIntent(Context context, IdpResponse idpResponse) {
183201
Intent in = new Intent();
184202
in.setClass(context, SignedInActivity.class);
203+
in.putExtra(EXTRA_IDP_RESPONSE, idpResponse);
185204
return in;
186205
}
187206
}

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,41 @@
9090
android:layout_height="wrap_content" />
9191

9292
</LinearLayout>
93+
</LinearLayout>
9394

95+
<LinearLayout
96+
android:id="@+id/idp_token_layout"
97+
android:layout_height="wrap_content"
98+
android:layout_width="wrap_content"
99+
android:orientation="vertical">
100+
<TextView
101+
style="@style/Base.TextAppearance.AppCompat.Subhead"
102+
android:layout_width="wrap_content"
103+
android:layout_height="wrap_content"
104+
android:text="@string/idp_token"/>
105+
106+
<TextView
107+
android:id="@+id/idp_token"
108+
android:layout_width="wrap_content"
109+
android:layout_height="wrap_content" />
110+
</LinearLayout>
111+
112+
<LinearLayout
113+
android:id="@+id/idp_secret_layout"
114+
android:layout_height="wrap_content"
115+
android:layout_width="wrap_content"
116+
android:orientation="vertical">
117+
<TextView
118+
style="@style/Base.TextAppearance.AppCompat.Subhead"
119+
android:layout_width="wrap_content"
120+
android:layout_height="wrap_content"
121+
android:text="@string/idp_secret"/>
122+
123+
<TextView
124+
android:id="@+id/idp_secret"
125+
android:layout_width="wrap_content"
126+
android:layout_height="wrap_content" />
94127
</LinearLayout>
95128

96129
</LinearLayout>
97-
</ScrollView>
130+
</ScrollView>

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,6 @@
5555
<string name="extra_facebook_scopes">Example extra Facebook scopes</string>
5656
<string name="friends">Friends</string>
5757
<string name="photos">Photos</string>
58+
<string name="idp_token">IDP Token</string>
59+
<string name="idp_secret">IDP Secret</string>
5860
</resources>

auth/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ startActivityForResult(
199199

200200
#### Handling the sign-in response
201201

202+
#####Response codes
202203
The authentication flow only provides three response codes:
203204
`Activity.RESULT_OK` if a user is signed in, `Activity.RESULT_CANCELLED` if
204205
sign in failed, and `ResultCodes.RESULT_NO_NETWORK` if sign in failed due to a lack of network connectivity.
@@ -239,6 +240,23 @@ see the
239240
[Firebase Auth documentation](https://firebase.google.com/docs/auth/android/manage-users#get_the_currently_signed-in_user)
240241
for more information.
241242

243+
##### ID Tokens
244+
To retrieve the ID token that the IDP returned, you can extract an `IdpResponse` from the result
245+
Intent.
246+
247+
```java
248+
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
249+
super.onActivityResult(requestCode, resultCode, data);
250+
if (resultCode == RESULT_OK) {
251+
IdpResponse idpResponse = IdpResponse.fromResultIntent(data);
252+
startActivity(new Intent(this, WelcomeBackActivity.class)
253+
.putExtra("my_token". idpResponse.getIdpToken()));
254+
}
255+
}
256+
```
257+
258+
Twitter also returns an AuthToken Secret which can be accessed with `idpResponse.getIdpSecret()`.
259+
242260
### Sign out
243261

244262
With the integrations provided by AuthUI, signing out a user is a multi-stage process:

auth/src/main/AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
android:label="@string/default_toolbar_title"
4040
android:theme="@style/FirebaseUI.Translucent" />
4141
<activity
42-
android:name="com.firebase.ui.auth.ui.account_link.WelcomeBackIDPPrompt"
42+
android:name="com.firebase.ui.auth.ui.account_link.WelcomeBackIdpPrompt"
4343
android:label="@string/title_welcome_back_idp_prompt"
4444
android:theme="@style/FirebaseUI" />
4545
<activity
@@ -51,7 +51,7 @@
5151
android:label="@string/default_toolbar_title"
5252
android:theme="@style/FirebaseUI" />
5353
<activity
54-
android:name="com.firebase.ui.auth.ui.idp.IDPSignInContainerActivity"
54+
android:name="com.firebase.ui.auth.ui.idp.IdpSignInContainerActivity"
5555
android:label="@string/default_toolbar_title"
5656
android:theme="@style/FirebaseUI.Translucent" />
5757
<activity

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import android.support.annotation.VisibleForTesting;
2727
import com.facebook.FacebookSdk;
2828
import com.facebook.login.LoginManager;
29-
import com.firebase.ui.auth.provider.TwitterProvider;
3029
import com.firebase.ui.auth.ui.ChooseAccountActivity;
3130
import com.firebase.ui.auth.ui.FlowParameters;
3231
import com.firebase.ui.auth.ui.idp.AuthMethodPickerActivity;
@@ -57,8 +56,6 @@
5756
import java.util.LinkedHashSet;
5857
import java.util.List;
5958
import java.util.Set;
60-
import java.util.SortedSet;
61-
import java.util.TreeSet;
6259

6360
/**
6461
* The entry point to the AuthUI authentication flow, and related utility methods.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the
10+
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
* express or implied. See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
15+
package com.firebase.ui.auth;
16+
17+
import android.content.Intent;
18+
import android.os.Parcel;
19+
import android.os.Parcelable;
20+
import android.support.annotation.Nullable;
21+
import com.firebase.ui.auth.ui.ExtraConstants;
22+
23+
/**
24+
* A container that encapsulates the result of authenticating with an Identity Provider.
25+
*/
26+
public class IdpResponse implements Parcelable {
27+
28+
private final String mProviderId;
29+
@Nullable private final String mEmail;
30+
private final String mToken;
31+
private final String mSecret;
32+
33+
public IdpResponse(String providerId, @Nullable String email) {
34+
this(providerId, email, null, null);
35+
}
36+
37+
public IdpResponse(
38+
String providerId, @Nullable String email, @Nullable String token) {
39+
this(providerId, email, token, null);
40+
}
41+
42+
public IdpResponse(
43+
String providerId,
44+
@Nullable String email,
45+
@Nullable String token,
46+
@Nullable String secret) {
47+
mProviderId = providerId;
48+
mEmail = email;
49+
mToken = token;
50+
mSecret = secret;
51+
}
52+
53+
public static final Creator<IdpResponse> CREATOR = new Creator<IdpResponse>() {
54+
@Override
55+
public IdpResponse createFromParcel(Parcel in) {
56+
return new IdpResponse(
57+
in.readString(),
58+
in.readString(),
59+
in.readString(),
60+
in.readString()
61+
);
62+
}
63+
64+
@Override
65+
public IdpResponse[] newArray(int size) {
66+
return new IdpResponse[size];
67+
}
68+
};
69+
70+
/**
71+
* Get the type of provider. e.g. {@link AuthUI#GOOGLE_PROVIDER}
72+
*/
73+
public String getProviderType() {
74+
return mProviderId;
75+
}
76+
77+
/**
78+
* Get the token received as a result of logging in with the specified IDP
79+
*/
80+
@Nullable
81+
public String getIdpToken() {
82+
return mToken;
83+
}
84+
85+
/**
86+
* Twitter only. Return the token secret received as a result of logging in with Twitter.
87+
*/
88+
@Nullable
89+
public String getIdpSecret() {
90+
return mSecret;
91+
}
92+
93+
/**
94+
* Get the email used to sign in.
95+
*/
96+
@Nullable
97+
public String getEmail() {
98+
return mEmail;
99+
}
100+
101+
@Override
102+
public int describeContents() {
103+
return 0;
104+
}
105+
106+
@Override
107+
public void writeToParcel(Parcel dest, int flags) {
108+
dest.writeString(mProviderId);
109+
dest.writeString(mEmail);
110+
dest.writeString(mToken);
111+
dest.writeString(mSecret);
112+
}
113+
114+
/**
115+
* Extract the {@link IdpResponse} from the flow's result intent.
116+
* @param resultIntent The intent which {@code onActivityResult} was called with.
117+
* @return The IdpResponse containing the token(s) from signing in with the Idp
118+
*/
119+
@Nullable
120+
public static IdpResponse fromResultIntent(Intent resultIntent) {
121+
return resultIntent.getParcelableExtra(ExtraConstants.EXTRA_IDP_RESPONSE);
122+
}
123+
}

0 commit comments

Comments
 (0)