-
Notifications
You must be signed in to change notification settings - Fork 624
Add dynamic module support to Firestore #2432
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
bbf7faa
e0d512a
a9984aa
5ecb626
f28f823
cbdc18d
2a32b7a
38d236a
e52d063
1a750cb
306fe80
7a83a63
dc839de
c049e31
28e3713
d55cf30
991f35e
72fc8cb
db16188
6cd946f
6829deb
5739d32
05d3fb9
a435e3b
7c0bb34
be0a08e
90403bc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -14,17 +14,22 @@ | |||||||||||||||||
|
||||||||||||||||||
package com.google.firebase.firestore.auth; | ||||||||||||||||||
|
||||||||||||||||||
import android.annotation.SuppressLint; | ||||||||||||||||||
import androidx.annotation.GuardedBy; | ||||||||||||||||||
import androidx.annotation.NonNull; | ||||||||||||||||||
import androidx.annotation.Nullable; | ||||||||||||||||||
import com.google.android.gms.tasks.Task; | ||||||||||||||||||
import com.google.android.gms.tasks.Tasks; | ||||||||||||||||||
import com.google.firebase.FirebaseApiNotAvailableException; | ||||||||||||||||||
import com.google.firebase.FirebaseApp; | ||||||||||||||||||
import com.google.firebase.auth.GetTokenResult; | ||||||||||||||||||
import com.google.firebase.auth.internal.IdTokenListener; | ||||||||||||||||||
import com.google.firebase.auth.internal.InternalAuthProvider; | ||||||||||||||||||
import com.google.firebase.firestore.util.Executors; | ||||||||||||||||||
import com.google.firebase.firestore.util.Listener; | ||||||||||||||||||
import com.google.firebase.firestore.util.Logger; | ||||||||||||||||||
import com.google.firebase.inject.Deferred; | ||||||||||||||||||
import com.google.firebase.inject.Provider; | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* FirebaseAuthCredentialsProvider uses Firebase Auth via {@link FirebaseApp} to get an auth token. | ||||||||||||||||||
|
@@ -40,50 +45,54 @@ public final class FirebaseAuthCredentialsProvider extends CredentialsProvider { | |||||||||||||||||
|
||||||||||||||||||
private static final String LOG_TAG = "FirebaseAuthCredentialsProvider"; | ||||||||||||||||||
|
||||||||||||||||||
private final InternalAuthProvider authProvider; | ||||||||||||||||||
|
||||||||||||||||||
/** | ||||||||||||||||||
* The listener registered with FirebaseApp; used to stop receiving auth changes once | ||||||||||||||||||
* changeListener is removed. | ||||||||||||||||||
*/ | ||||||||||||||||||
private final IdTokenListener idTokenListener; | ||||||||||||||||||
private final IdTokenListener idTokenListener = result -> onIdTokenChanged(); | ||||||||||||||||||
|
||||||||||||||||||
/** The listener to be notified of credential changes (sign-in / sign-out, token changes). */ | ||||||||||||||||||
@Nullable private Listener<User> changeListener; | ||||||||||||||||||
/** | ||||||||||||||||||
* The {@link Provider} that gives access to the {@link InternalAuthProvider} instance; initially, | ||||||||||||||||||
* its {@link Provider#get} method returns {@code null}, but will be changed to a new {@link | ||||||||||||||||||
* Provider} once the "auth" module becomes available. | ||||||||||||||||||
*/ | ||||||||||||||||||
@Nullable | ||||||||||||||||||
@GuardedBy("this") | ||||||||||||||||||
private InternalAuthProvider internalAuthProvider; | ||||||||||||||||||
|
||||||||||||||||||
/** The current user as reported to us via our IdTokenListener. */ | ||||||||||||||||||
private User currentUser; | ||||||||||||||||||
/** The listener to be notified of credential changes (sign-in / sign-out, token changes). */ | ||||||||||||||||||
@Nullable | ||||||||||||||||||
@GuardedBy("this") | ||||||||||||||||||
private Listener<User> changeListener; | ||||||||||||||||||
|
||||||||||||||||||
/** Counter used to detect if the token changed while a getToken request was outstanding. */ | ||||||||||||||||||
@GuardedBy("this") | ||||||||||||||||||
private int tokenCounter; | ||||||||||||||||||
|
||||||||||||||||||
@GuardedBy("this") | ||||||||||||||||||
private boolean forceRefresh; | ||||||||||||||||||
|
||||||||||||||||||
/** Creates a new FirebaseAuthCredentialsProvider. */ | ||||||||||||||||||
public FirebaseAuthCredentialsProvider(InternalAuthProvider authProvider) { | ||||||||||||||||||
this.authProvider = authProvider; | ||||||||||||||||||
this.idTokenListener = | ||||||||||||||||||
token -> { | ||||||||||||||||||
@SuppressLint("ProviderAssignment") // TODO: Remove this @SuppressLint once b/181014061 is fixed. | ||||||||||||||||||
public FirebaseAuthCredentialsProvider(Deferred<InternalAuthProvider> deferredAuthProvider) { | ||||||||||||||||||
deferredAuthProvider.whenAvailable( | ||||||||||||||||||
provider -> { | ||||||||||||||||||
synchronized (this) { | ||||||||||||||||||
currentUser = getUser(); | ||||||||||||||||||
tokenCounter++; | ||||||||||||||||||
|
||||||||||||||||||
if (changeListener != null) { | ||||||||||||||||||
changeListener.onValue(currentUser); | ||||||||||||||||||
} | ||||||||||||||||||
internalAuthProvider = provider.get(); | ||||||||||||||||||
onIdTokenChanged(); | ||||||||||||||||||
internalAuthProvider.addIdTokenListener(idTokenListener); | ||||||||||||||||||
} | ||||||||||||||||||
}; | ||||||||||||||||||
currentUser = getUser(); | ||||||||||||||||||
tokenCounter = 0; | ||||||||||||||||||
|
||||||||||||||||||
authProvider.addIdTokenListener(idTokenListener); | ||||||||||||||||||
}); | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
@Override | ||||||||||||||||||
public synchronized Task<String> getToken() { | ||||||||||||||||||
boolean doForceRefresh = forceRefresh; | ||||||||||||||||||
if (internalAuthProvider == null) { | ||||||||||||||||||
return Tasks.forException(new FirebaseApiNotAvailableException("auth is not available")); | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you sure you want to throw in this case? Shouldn't this case be treated the same as it is in the EmptyCredentialsProvider and return Lines 25 to 29 in 18d574f
Additionally, is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should fall back to "unauthenticated" auth and return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that throwing Lines 62 to 64 in 34bf6dc
By failing with Regarding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please fix. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What are your thoughts on this in light of the code in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your answer wasn't quite what I predicted. You have changed my mind. I was expecting the consumer to be a bit simpler than it actually is. Please disregard. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. I've left the |
||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
Task<GetTokenResult> res = internalAuthProvider.getAccessToken(forceRefresh); | ||||||||||||||||||
forceRefresh = false; | ||||||||||||||||||
Task<GetTokenResult> res = authProvider.getAccessToken(doForceRefresh); | ||||||||||||||||||
|
||||||||||||||||||
// Take note of the current value of the tokenCounter so that this method can fail (with a | ||||||||||||||||||
// FirebaseFirestoreException) if there is a token change while the request is outstanding. | ||||||||||||||||||
|
@@ -118,18 +127,29 @@ public synchronized void setChangeListener(@NonNull Listener<User> changeListene | |||||||||||||||||
this.changeListener = changeListener; | ||||||||||||||||||
|
||||||||||||||||||
// Fire the initial event. | ||||||||||||||||||
changeListener.onValue(currentUser); | ||||||||||||||||||
changeListener.onValue(getUser()); | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
@Override | ||||||||||||||||||
public synchronized void removeChangeListener() { | ||||||||||||||||||
changeListener = null; | ||||||||||||||||||
authProvider.removeIdTokenListener(idTokenListener); | ||||||||||||||||||
|
||||||||||||||||||
if (internalAuthProvider != null) { | ||||||||||||||||||
internalAuthProvider.removeIdTokenListener(idTokenListener); | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** Invoked when the auth token changes. */ | ||||||||||||||||||
private synchronized void onIdTokenChanged() { | ||||||||||||||||||
tokenCounter++; | ||||||||||||||||||
if (changeListener != null) { | ||||||||||||||||||
changeListener.onValue(getUser()); | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
/** Returns the current {@link User} as obtained from the given FirebaseApp instance. */ | ||||||||||||||||||
private User getUser() { | ||||||||||||||||||
@Nullable String uid = authProvider.getUid(); | ||||||||||||||||||
/** Returns the current {@link User} as obtained from the given InternalAuthProvider. */ | ||||||||||||||||||
private synchronized User getUser() { | ||||||||||||||||||
@Nullable String uid = (internalAuthProvider == null) ? null : internalAuthProvider.getUid(); | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the internalAuthProvider ever null? Looks like you initialize it to a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never mind, I got confused because this is a |
||||||||||||||||||
return uid != null ? new User(uid) : User.UNAUTHENTICATED; | ||||||||||||||||||
} | ||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is currently not
nullable
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.