Skip to content
This repository was archived by the owner on Jun 29, 2022. It is now read-only.

Commit 4d5ab95

Browse files
authored
Deferring the initialization of FirebaseUserManager (firebase#269)
1 parent 55d403f commit 4d5ab95

File tree

3 files changed

+31
-16
lines changed

3 files changed

+31
-16
lines changed

src/main/java/com/google/firebase/auth/FirebaseAuth.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,21 @@ public class FirebaseAuth {
6767
private final Supplier<FirebaseTokenFactory> tokenFactory;
6868
private final Supplier<? extends FirebaseTokenVerifier> idTokenVerifier;
6969
private final Supplier<? extends FirebaseTokenVerifier> cookieVerifier;
70+
private final Supplier<? extends FirebaseUserManager> userManager;
7071
private final JsonFactory jsonFactory;
71-
private final FirebaseUserManager userManager;
7272

7373
private FirebaseAuth(Builder builder) {
7474
this.firebaseApp = checkNotNull(builder.firebaseApp);
7575
this.tokenFactory = threadSafeMemoize(builder.tokenFactory);
7676
this.idTokenVerifier = threadSafeMemoize(builder.idTokenVerifier);
7777
this.cookieVerifier = threadSafeMemoize(builder.cookieVerifier);
78+
this.userManager = threadSafeMemoize(new Supplier<FirebaseUserManager>() {
79+
@Override
80+
public FirebaseUserManager get() {
81+
return new FirebaseUserManager(firebaseApp);
82+
}
83+
});
7884
this.jsonFactory = firebaseApp.getOptions().getJsonFactory();
79-
this.userManager = new FirebaseUserManager(firebaseApp);
8085
}
8186

8287
/**
@@ -139,6 +144,7 @@ private CallableOperation<String, FirebaseAuthException> createSessionCookieOp(
139144
checkNotDestroyed();
140145
checkArgument(!Strings.isNullOrEmpty(idToken), "idToken must not be null or empty");
141146
checkNotNull(options, "options must not be null");
147+
final FirebaseUserManager userManager = getUserManager();
142148
return new CallableOperation<String, FirebaseAuthException>() {
143149
@Override
144150
protected String execute() throws FirebaseAuthException {
@@ -225,6 +231,7 @@ public FirebaseToken execute() throws FirebaseAuthException {
225231
FirebaseTokenVerifier getSessionCookieVerifier(boolean checkRevoked) {
226232
FirebaseTokenVerifier verifier = cookieVerifier.get();
227233
if (checkRevoked) {
234+
FirebaseUserManager userManager = getUserManager();
228235
verifier = RevocationCheckDecorator.decorateSessionCookieVerifier(verifier, userManager);
229236
}
230237
return verifier;
@@ -432,6 +439,7 @@ protected FirebaseToken execute() throws FirebaseAuthException {
432439
FirebaseTokenVerifier getIdTokenVerifier(boolean checkRevoked) {
433440
FirebaseTokenVerifier verifier = idTokenVerifier.get();
434441
if (checkRevoked) {
442+
FirebaseUserManager userManager = getUserManager();
435443
verifier = RevocationCheckDecorator.decorateIdTokenVerifier(verifier, userManager);
436444
}
437445
return verifier;
@@ -472,6 +480,7 @@ public ApiFuture<Void> revokeRefreshTokensAsync(@NonNull String uid) {
472480
private CallableOperation<Void, FirebaseAuthException> revokeRefreshTokensOp(final String uid) {
473481
checkNotDestroyed();
474482
checkArgument(!Strings.isNullOrEmpty(uid), "uid must not be null or empty");
483+
final FirebaseUserManager userManager = getUserManager();
475484
return new CallableOperation<Void, FirebaseAuthException>() {
476485
@Override
477486
protected Void execute() throws FirebaseAuthException {
@@ -511,6 +520,7 @@ public ApiFuture<UserRecord> getUserAsync(@NonNull String uid) {
511520
private CallableOperation<UserRecord, FirebaseAuthException> getUserOp(final String uid) {
512521
checkNotDestroyed();
513522
checkArgument(!Strings.isNullOrEmpty(uid), "uid must not be null or empty");
523+
final FirebaseUserManager userManager = getUserManager();
514524
return new CallableOperation<UserRecord, FirebaseAuthException>() {
515525
@Override
516526
protected UserRecord execute() throws FirebaseAuthException {
@@ -548,6 +558,7 @@ private CallableOperation<UserRecord, FirebaseAuthException> getUserByEmailOp(
548558
final String email) {
549559
checkNotDestroyed();
550560
checkArgument(!Strings.isNullOrEmpty(email), "email must not be null or empty");
561+
final FirebaseUserManager userManager = getUserManager();
551562
return new CallableOperation<UserRecord, FirebaseAuthException>() {
552563
@Override
553564
protected UserRecord execute() throws FirebaseAuthException {
@@ -585,6 +596,7 @@ private CallableOperation<UserRecord, FirebaseAuthException> getUserByPhoneNumbe
585596
final String phoneNumber) {
586597
checkNotDestroyed();
587598
checkArgument(!Strings.isNullOrEmpty(phoneNumber), "phone number must not be null or empty");
599+
final FirebaseUserManager userManager = getUserManager();
588600
return new CallableOperation<UserRecord, FirebaseAuthException>() {
589601
@Override
590602
protected UserRecord execute() throws FirebaseAuthException {
@@ -652,6 +664,7 @@ public ApiFuture<ListUsersPage> listUsersAsync(@Nullable String pageToken, int m
652664
private CallableOperation<ListUsersPage, FirebaseAuthException> listUsersOp(
653665
@Nullable final String pageToken, final int maxResults) {
654666
checkNotDestroyed();
667+
final FirebaseUserManager userManager = getUserManager();
655668
final PageFactory factory = new PageFactory(
656669
new DefaultUserSource(userManager, jsonFactory), maxResults, pageToken);
657670
return new CallableOperation<ListUsersPage, FirebaseAuthException>() {
@@ -692,6 +705,7 @@ private CallableOperation<UserRecord, FirebaseAuthException> createUserOp(
692705
final CreateRequest request) {
693706
checkNotDestroyed();
694707
checkNotNull(request, "create request must not be null");
708+
final FirebaseUserManager userManager = getUserManager();
695709
return new CallableOperation<UserRecord, FirebaseAuthException>() {
696710
@Override
697711
protected UserRecord execute() throws FirebaseAuthException {
@@ -731,6 +745,7 @@ private CallableOperation<UserRecord, FirebaseAuthException> updateUserOp(
731745
final UpdateRequest request) {
732746
checkNotDestroyed();
733747
checkNotNull(request, "update request must not be null");
748+
final FirebaseUserManager userManager = getUserManager();
734749
return new CallableOperation<UserRecord, FirebaseAuthException>() {
735750
@Override
736751
protected UserRecord execute() throws FirebaseAuthException {
@@ -783,6 +798,7 @@ private CallableOperation<Void, FirebaseAuthException> setCustomUserClaimsOp(
783798
final String uid, final Map<String, Object> claims) {
784799
checkNotDestroyed();
785800
checkArgument(!Strings.isNullOrEmpty(uid), "uid must not be null or empty");
801+
final FirebaseUserManager userManager = getUserManager();
786802
return new CallableOperation<Void, FirebaseAuthException>() {
787803
@Override
788804
protected Void execute() throws FirebaseAuthException {
@@ -820,6 +836,7 @@ public ApiFuture<Void> deleteUserAsync(String uid) {
820836
private CallableOperation<Void, FirebaseAuthException> deleteUserOp(final String uid) {
821837
checkNotDestroyed();
822838
checkArgument(!Strings.isNullOrEmpty(uid), "uid must not be null or empty");
839+
final FirebaseUserManager userManager = getUserManager();
823840
return new CallableOperation<Void, FirebaseAuthException>() {
824841
@Override
825842
protected Void execute() throws FirebaseAuthException {
@@ -901,6 +918,7 @@ private CallableOperation<UserImportResult, FirebaseAuthException> importUsersOp
901918
final List<ImportUserRecord> users, final UserImportOptions options) {
902919
checkNotDestroyed();
903920
final UserImportRequest request = new UserImportRequest(users, options, jsonFactory);
921+
final FirebaseUserManager userManager = getUserManager();
904922
return new CallableOperation<UserImportResult, FirebaseAuthException>() {
905923
@Override
906924
protected UserImportResult execute() throws FirebaseAuthException {
@@ -1071,7 +1089,7 @@ public ApiFuture<String> generateSignInWithEmailLinkAsync(
10711089

10721090
@VisibleForTesting
10731091
FirebaseUserManager getUserManager() {
1074-
return this.userManager;
1092+
return this.userManager.get();
10751093
}
10761094

10771095
private CallableOperation<String, FirebaseAuthException> generateEmailActionLinkOp(
@@ -1081,6 +1099,7 @@ private CallableOperation<String, FirebaseAuthException> generateEmailActionLink
10811099
if (type == EmailLinkType.EMAIL_SIGNIN) {
10821100
checkNotNull(settings, "ActionCodeSettings must not be null when generating sign-in links");
10831101
}
1102+
final FirebaseUserManager userManager = getUserManager();
10841103
return new CallableOperation<String, FirebaseAuthException>() {
10851104
@Override
10861105
protected String execute() throws FirebaseAuthException {

src/test/java/com/google/firebase/auth/FirebaseAuthTest.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
import java.util.concurrent.atomic.AtomicInteger;
4747

4848
import org.junit.After;
49-
import org.junit.Assert;
5049
import org.junit.Test;
5150

5251
public class FirebaseAuthTest {
@@ -139,21 +138,12 @@ public void testInitAfterAppDelete() throws ExecutionException, InterruptedExcep
139138
}
140139

141140
@Test
142-
public void testProjectIdRequired() {
141+
public void testProjectIdNotRequiredAtInitialization() {
143142
FirebaseOptions options = FirebaseOptions.builder()
144143
.setCredentials(new MockGoogleCredentials())
145144
.build();
146145
FirebaseApp app = FirebaseApp.initializeApp(options, "testProjectIdRequired");
147-
try {
148-
FirebaseAuth.getInstance(app);
149-
fail("Expected exception.");
150-
} catch (IllegalArgumentException expected) {
151-
Assert.assertEquals(
152-
"Project ID is required to access the auth service. Use a service account credential "
153-
+ "or set the project ID explicitly via FirebaseOptions. Alternatively you can "
154-
+ "also set the project ID via the GOOGLE_CLOUD_PROJECT environment variable.",
155-
expected.getMessage());
156-
}
146+
assertNotNull(FirebaseAuth.getInstance(app));
157147
}
158148

159149
@Test(expected = IllegalArgumentException.class)

src/test/java/com/google/firebase/auth/FirebaseUserManagerTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,16 @@ public void testProjectIdRequired() {
8585
FirebaseApp.initializeApp(new FirebaseOptions.Builder()
8686
.setCredentials(credentials)
8787
.build());
88+
FirebaseAuth auth = FirebaseAuth.getInstance();
8889
try {
89-
FirebaseAuth.getInstance();
90+
auth.getUserManager();
9091
fail("No error thrown for missing project ID");
9192
} catch (IllegalArgumentException expected) {
93+
assertEquals(
94+
"Project ID is required to access the auth service. Use a service account credential "
95+
+ "or set the project ID explicitly via FirebaseOptions. Alternatively you can "
96+
+ "also set the project ID via the GOOGLE_CLOUD_PROJECT environment variable.",
97+
expected.getMessage());
9298
}
9399
}
94100

0 commit comments

Comments
 (0)