Skip to content

Commit 8bda799

Browse files
authored
Merge pull request #1373 from firebase/version-4.1.0
Version 4.1.0
2 parents 9aceabb + 32f67f4 commit 8bda799

File tree

207 files changed

+4847
-3941
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

207 files changed

+4847
-3941
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,16 @@ libraries.
4747
```groovy
4848
dependencies {
4949
// FirebaseUI for Firebase Realtime Database
50-
implementation 'com.firebaseui:firebase-ui-database:4.0.1'
50+
implementation 'com.firebaseui:firebase-ui-database:4.1.0'
5151
5252
// FirebaseUI for Cloud Firestore
53-
implementation 'com.firebaseui:firebase-ui-firestore:4.0.1'
53+
implementation 'com.firebaseui:firebase-ui-firestore:4.1.0'
5454
5555
// FirebaseUI for Firebase Auth
56-
implementation 'com.firebaseui:firebase-ui-auth:4.0.1'
56+
implementation 'com.firebaseui:firebase-ui-auth:4.1.0'
5757
5858
// FirebaseUI for Cloud Storage
59-
implementation 'com.firebaseui:firebase-ui-storage:4.0.1'
59+
implementation 'com.firebaseui:firebase-ui-storage:4.1.0'
6060
}
6161
```
6262

@@ -99,7 +99,7 @@ versions. This means that FirebaseUI has independent dependencies on each of the
9999
For best results, your app should depend on a version of each dependency with the same major
100100
version number as the version used by FirebaseUI.
101101

102-
As of version `4.0.0`, FirebaseUI has the following dependency versions:
102+
As of version `4.1.0`, FirebaseUI has the following dependency versions:
103103

104104
| Library | Version |
105105
|----------------------|--------------------------------|

app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
<activity
3838
android:name=".auth.SignedInActivity"
3939
android:label="@string/title_auth_activity" />
40+
<activity
41+
android:name=".auth.AnonymousUpgradeActivity"
42+
android:label="@string/title_anonymous_upgrade"/>
4043

4144
<!-- Firestore demo -->
4245
<activity

app/src/main/java/com/firebase/uidemo/ChooserActivity.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import android.view.ViewGroup;
2727
import android.widget.TextView;
2828

29+
import com.firebase.uidemo.auth.AnonymousUpgradeActivity;
2930
import com.firebase.uidemo.auth.AuthUiActivity;
3031
import com.firebase.uidemo.database.firestore.FirestoreChatActivity;
3132
import com.firebase.uidemo.database.firestore.FirestorePagingActivity;
@@ -53,6 +54,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
5354
private static class ActivityChooserAdapter extends RecyclerView.Adapter<ActivityStarterHolder> {
5455
private static final Class[] CLASSES = new Class[]{
5556
AuthUiActivity.class,
57+
AnonymousUpgradeActivity.class,
5658
FirestoreChatActivity.class,
5759
FirestorePagingActivity.class,
5860
RealtimeDbChatActivity.class,
@@ -61,6 +63,7 @@ private static class ActivityChooserAdapter extends RecyclerView.Adapter<Activit
6163

6264
private static final int[] DESCRIPTION_NAMES = new int[]{
6365
R.string.title_auth_activity,
66+
R.string.title_anonymous_upgrade,
6467
R.string.title_firestore_activity,
6568
R.string.title_firestore_paging_activity,
6669
R.string.title_realtime_database_activity,
@@ -69,6 +72,7 @@ private static class ActivityChooserAdapter extends RecyclerView.Adapter<Activit
6972

7073
private static final int[] DESCRIPTION_IDS = new int[]{
7174
R.string.desc_auth,
75+
R.string.desc_anonymous_upgrade,
7276
R.string.desc_firestore,
7377
R.string.desc_firestore_paging,
7478
R.string.desc_realtime_database,
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
package com.firebase.uidemo.auth;
2+
3+
import android.content.Intent;
4+
import android.os.Bundle;
5+
import android.support.annotation.NonNull;
6+
import android.support.v7.app.AppCompatActivity;
7+
import android.text.TextUtils;
8+
import android.util.Log;
9+
import android.widget.Button;
10+
import android.widget.TextView;
11+
import android.widget.Toast;
12+
13+
import com.firebase.ui.auth.AuthUI;
14+
import com.firebase.ui.auth.ErrorCodes;
15+
import com.firebase.ui.auth.IdpResponse;
16+
import com.firebase.uidemo.R;
17+
import com.firebase.uidemo.util.ConfigurationUtils;
18+
import com.google.android.gms.tasks.OnCompleteListener;
19+
import com.google.android.gms.tasks.Task;
20+
import com.google.firebase.auth.AuthCredential;
21+
import com.google.firebase.auth.AuthResult;
22+
import com.google.firebase.auth.FirebaseAuth;
23+
import com.google.firebase.auth.FirebaseUser;
24+
25+
import java.util.List;
26+
27+
import butterknife.BindView;
28+
import butterknife.ButterKnife;
29+
import butterknife.OnClick;
30+
31+
public class AnonymousUpgradeActivity extends AppCompatActivity {
32+
33+
private static final String TAG = "AccountLink";
34+
35+
private static final int RC_SIGN_IN = 123;
36+
37+
@BindView(R.id.status_text)
38+
TextView mStatus;
39+
40+
@BindView(R.id.anon_sign_in)
41+
Button mAnonSignInButton;
42+
43+
@BindView(R.id.begin_flow)
44+
Button mLaunchUIButton;
45+
46+
@BindView(R.id.resolve_merge)
47+
Button mResolveMergeButton;
48+
49+
@BindView(R.id.sign_out)
50+
Button mSignOutButton;
51+
52+
private AuthCredential mPendingCredential;
53+
54+
@Override
55+
protected void onCreate(Bundle savedInstanceState) {
56+
super.onCreate(savedInstanceState);
57+
setContentView(R.layout.activity_anonymous_upgrade);
58+
ButterKnife.bind(this);
59+
}
60+
61+
@OnClick(R.id.anon_sign_in)
62+
public void signInAnonymously() {
63+
FirebaseAuth.getInstance().signInAnonymously()
64+
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
65+
@Override
66+
public void onComplete(@NonNull Task<AuthResult> task) {
67+
updateUI();
68+
69+
if (task.isSuccessful()) {
70+
setStatus("Signed in anonymously as user "
71+
+ getUserIdentifier(task.getResult().getUser()));
72+
} else {
73+
setStatus("Anonymous sign in failed.");
74+
}
75+
}
76+
});
77+
}
78+
79+
@OnClick(R.id.begin_flow)
80+
public void startAuthUI() {
81+
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
82+
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
83+
.setLogo(R.drawable.firebase_auth_120dp)
84+
.setAvailableProviders(providers)
85+
.setIsSmartLockEnabled(false)
86+
.enableAnonymousUsersAutoUpgrade()
87+
.build();
88+
startActivityForResult(intent, RC_SIGN_IN);
89+
}
90+
91+
@OnClick(R.id.resolve_merge)
92+
public void resolveMerge() {
93+
if (mPendingCredential == null) {
94+
Toast.makeText(this, "Nothing to resolve.", Toast.LENGTH_SHORT).show();
95+
return;
96+
}
97+
98+
// TODO: Show how to do good data moving
99+
100+
FirebaseAuth.getInstance().signInWithCredential(mPendingCredential)
101+
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
102+
@Override
103+
public void onComplete(@NonNull Task<AuthResult> task) {
104+
mPendingCredential = null;
105+
updateUI();
106+
107+
if (task.isSuccessful()) {
108+
setStatus("Signed in as " + getUserIdentifier(task.getResult().getUser()));
109+
} else {
110+
Log.w(TAG, "Merge failed", task.getException());
111+
setStatus("Failed to resolve merge conflict, see logs.");
112+
}
113+
}
114+
});
115+
}
116+
117+
@OnClick(R.id.sign_out)
118+
public void signOut() {
119+
AuthUI.getInstance().signOut(this)
120+
.addOnCompleteListener(new OnCompleteListener<Void>() {
121+
@Override
122+
public void onComplete(@NonNull Task<Void> task) {
123+
setStatus(null);
124+
updateUI();
125+
}
126+
});
127+
}
128+
129+
@Override
130+
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
131+
super.onActivityResult(requestCode, resultCode, data);
132+
if (requestCode == RC_SIGN_IN) {
133+
IdpResponse response = IdpResponse.fromResultIntent(data);
134+
if (response == null) {
135+
// User pressed back button
136+
return;
137+
}
138+
if (resultCode == RESULT_OK) {
139+
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance().getCurrentUser()));
140+
} else {
141+
if (response.getError().getErrorCode() == ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
142+
setStatus("Merge conflict: user already exists.");
143+
mResolveMergeButton.setEnabled(true);
144+
mPendingCredential = response.getCredentialForLinking();
145+
}
146+
}
147+
148+
updateUI();
149+
}
150+
}
151+
152+
private void updateUI() {
153+
FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
154+
155+
if (currentUser == null) {
156+
// Not signed in
157+
mAnonSignInButton.setEnabled(true);
158+
mLaunchUIButton.setEnabled(false);
159+
mResolveMergeButton.setEnabled(false);
160+
mSignOutButton.setEnabled(false);
161+
} else if (mPendingCredential == null && currentUser.isAnonymous()) {
162+
// Anonymous user, waiting for linking
163+
mAnonSignInButton.setEnabled(false);
164+
mLaunchUIButton.setEnabled(true);
165+
mResolveMergeButton.setEnabled(false);
166+
mSignOutButton.setEnabled(true);
167+
} else if (mPendingCredential == null && !currentUser.isAnonymous()) {
168+
// Fully signed in
169+
mAnonSignInButton.setEnabled(false);
170+
mLaunchUIButton.setEnabled(false);
171+
mResolveMergeButton.setEnabled(false);
172+
mSignOutButton.setEnabled(true);
173+
} else if (mPendingCredential != null) {
174+
// Signed in anonymous, awaiting merge conflict
175+
mAnonSignInButton.setEnabled(false);
176+
mLaunchUIButton.setEnabled(false);
177+
mResolveMergeButton.setEnabled(true);
178+
mSignOutButton.setEnabled(true);
179+
}
180+
}
181+
182+
private void setStatus(String message) {
183+
mStatus.setText(message);
184+
}
185+
186+
private String getUserIdentifier(FirebaseUser user) {
187+
if (user.isAnonymous()) {
188+
return user.getUid();
189+
} else if (!TextUtils.isEmpty(user.getEmail())) {
190+
return user.getEmail();
191+
} else if (!TextUtils.isEmpty(user.getPhoneNumber())) {
192+
return user.getPhoneNumber();
193+
} else {
194+
return "unknown";
195+
}
196+
}
197+
}

0 commit comments

Comments
 (0)