() {
+ @Override
+ protected String execute() throws FirebaseAuthException {
+ return userManager.createSessionCookie(idToken, options);
+ }
+ };
}
/**
* Parses and verifies a Firebase session cookie.
*
- * If verified successfully, the returned {@code ApiFuture} completes with a parsed version of
- * the cookie from which the UID and the other claims can be read. If the cookie is invalid,
- * the future throws an exception indicating the failure.
+ *
If verified successfully, returns a parsed version of the cookie from which the UID and the
+ * other claims can be read. If the cookie is invalid, throws a {@link FirebaseAuthException}.
*
*
This method does not check whether the cookie has been revoked. See
- * {@link #verifySessionCookieAsync(String, boolean)}.
+ * {@link #verifySessionCookie(String, boolean)}.
*
* @param cookie A Firebase session cookie string to verify and parse.
- * @return An {@code ApiFuture} which will complete successfully with the parsed cookie, or
- * unsuccessfully with the failure Exception.
+ * @return A {@link FirebaseToken} representing the verified and decoded cookie.
*/
- public ApiFuture verifySessionCookieAsync(String cookie) {
- return new TaskToApiFuture<>(verifySessionCookie(cookie, false));
+ public FirebaseToken verifySessionCookie(String cookie) throws FirebaseAuthException {
+ return verifySessionCookie(cookie, false);
}
/**
@@ -164,10 +181,34 @@ public ApiFuture verifySessionCookieAsync(String cookie) {
* If {@code checkRevoked} is true, additionally verifies that the cookie has not been
* revoked.
*
- *
If verified successfully, the returned {@code ApiFuture} completes with a parsed version of
- * the cookie from which the UID and the other claims can be read. If the cookie is invalid or
- * has been revoked while {@code checkRevoked} is true, the future throws an exception indicating
- * the failure.
+ *
If verified successfully, returns a parsed version of the cookie from which the UID and the
+ * other claims can be read. If the cookie is invalid or has been revoked while
+ * {@code checkRevoked} is true, throws a {@link FirebaseAuthException}.
+ *
+ * @param cookie A Firebase session cookie string to verify and parse.
+ * @param checkRevoked A boolean indicating whether to check if the cookie was explicitly
+ * revoked.
+ * @return A {@link FirebaseToken} representing the verified and decoded cookie.
+ */
+ public FirebaseToken verifySessionCookie(
+ String cookie, boolean checkRevoked) throws FirebaseAuthException {
+ return verifySessionCookieOp(cookie, checkRevoked).call();
+ }
+
+ /**
+ * Similar to {@link #verifySessionCookie(String)} but performs the operation asynchronously.
+ *
+ * @param cookie A Firebase session cookie string to verify and parse.
+ * @return An {@code ApiFuture} which will complete successfully with the parsed cookie, or
+ * unsuccessfully with the failure Exception.
+ */
+ public ApiFuture verifySessionCookieAsync(String cookie) {
+ return verifySessionCookieAsync(cookie, false);
+ }
+
+ /**
+ * Similar to {@link #verifySessionCookie(String, boolean)} but performs the operation
+ * asynchronously.
*
* @param cookie A Firebase session cookie string to verify and parse.
* @param checkRevoked A boolean indicating whether to check if the cookie was explicitly
@@ -176,19 +217,26 @@ public ApiFuture verifySessionCookieAsync(String cookie) {
* unsuccessfully with the failure Exception.
*/
public ApiFuture verifySessionCookieAsync(String cookie, boolean checkRevoked) {
- return new TaskToApiFuture<>(verifySessionCookie(cookie, checkRevoked));
+ return verifySessionCookieOp(cookie, checkRevoked).callAsync(firebaseApp);
}
- private Task verifySessionCookie(final String cookie, final boolean checkRevoked) {
+ private CallableOperation verifySessionCookieOp(
+ final String cookie, final boolean checkRevoked) {
checkNotDestroyed();
checkState(!Strings.isNullOrEmpty(projectId),
"Must initialize FirebaseApp with a project ID to call verifySessionCookie()");
- return call(new Callable() {
+ return new CallableOperation() {
@Override
- public FirebaseToken call() throws Exception {
+ public FirebaseToken execute() throws FirebaseAuthException {
FirebaseTokenVerifier firebaseTokenVerifier =
FirebaseTokenVerifier.createSessionCookieVerifier(projectId, keyManagers, clock);
- FirebaseToken firebaseToken = FirebaseToken.parse(jsonFactory, cookie);
+ FirebaseToken firebaseToken;
+ try {
+ firebaseToken = FirebaseToken.parse(jsonFactory, cookie);
+ } catch (IOException e) {
+ throw new FirebaseAuthException(ERROR_INVALID_SESSION_COOKIE,
+ "Failed to parse cookie", e);
+ }
// This will throw a FirebaseAuthException with details on how the token is invalid.
firebaseTokenVerifier.verifyTokenAndSignature(firebaseToken.getToken());
@@ -198,7 +246,7 @@ public FirebaseToken call() throws Exception {
}
return firebaseToken;
}
- });
+ };
}
private void checkRevoked(
@@ -212,106 +260,202 @@ private void checkRevoked(
}
/**
- * Similar to {@link #createCustomTokenAsync(String)}, but returns a {@link Task}.
+ * Creates a Firebase custom token for the given UID. This token can then be sent back to a client
+ * application to be used with the
+ * signInWithCustomToken
+ * authentication API.
+ *
+ * {@link FirebaseApp} must have been initialized with service account credentials to use
+ * call this method.
*
* @param uid The UID to store in the token. This identifies the user to other Firebase services
- * (Firebase Database, Firebase Auth, etc.)
- * @return A {@link Task} which will complete successfully with the created Firebase Custom Token,
- * or unsuccessfully with the failure Exception.
- * @deprecated Use {@link #createCustomTokenAsync(String)}
+ * (Realtime Database, Firebase Auth, etc.). Should be less than 128 characters.
+ * @return A Firebase custom token string.
+ * @throws IllegalArgumentException If the specified uid is null or empty, or if the app has not
+ * been initialized with service account credentials.
+ * @throws FirebaseAuthException If an error occurs while generating the custom token.
*/
- public Task createCustomToken(String uid) {
+ public String createCustomToken(@NonNull String uid) throws FirebaseAuthException {
return createCustomToken(uid, null);
}
/**
- * Similar to {@link #createCustomTokenAsync(String, Map)}, but returns a {@link Task}.
+ * Creates a Firebase custom token for the given UID, containing the specified additional
+ * claims. This token can then be sent back to a client application to be used with the
+ * signInWithCustomToken
+ * authentication API.
+ *
+ * {@link FirebaseApp} must have been initialized with service account credentials to use
+ * call this method.
*
* @param uid The UID to store in the token. This identifies the user to other Firebase services
- * (Realtime Database, Storage, etc.). Should be less than 128 characters.
+ * (Realtime Database, Firebase Auth, etc.). Should be less than 128 characters.
* @param developerClaims Additional claims to be stored in the token (and made available to
* security rules in Database, Storage, etc.). These must be able to be serialized to JSON
* (e.g. contain only Maps, Arrays, Strings, Booleans, Numbers, etc.)
- * @return A {@link Task} which will complete successfully with the created Firebase Custom Token,
- * or unsuccessfully with the failure Exception.
- * @deprecated Use {@link #createCustomTokenAsync(String, Map)}
+ * @return A Firebase custom token string.
+ * @throws IllegalArgumentException If the specified uid is null or empty, or if the app has not
+ * been initialized with service account credentials.
+ * @throws FirebaseAuthException If an error occurs while generating the custom token.
*/
- public Task createCustomToken(
- final String uid, final Map developerClaims) {
- checkNotDestroyed();
- checkState(credentials instanceof ServiceAccountCredentials,
- "Must initialize FirebaseApp with a service account credential to call "
- + "createCustomToken()");
-
- final ServiceAccountCredentials serviceAccount = (ServiceAccountCredentials) credentials;
- return call(new Callable() {
- @Override
- public String call() throws Exception {
- FirebaseTokenFactory tokenFactory = FirebaseTokenFactory.getInstance();
- return tokenFactory.createSignedCustomAuthTokenForUser(
- uid,
- developerClaims,
- serviceAccount.getClientEmail(),
- serviceAccount.getPrivateKey());
- }
- });
+ public String createCustomToken(@NonNull String uid,
+ @Nullable Map developerClaims) throws FirebaseAuthException {
+ return createCustomTokenOp(uid, developerClaims).call();
}
/**
- * Creates a Firebase Custom Token associated with the given UID. This token can then be provided
- * back to a client application for use with the
- * signInWithCustomToken
- * authentication API.
+ * Similar to {@link #createCustomToken(String)} but performs the operation asynchronously.
*
* @param uid The UID to store in the token. This identifies the user to other Firebase services
- * (Firebase Realtime Database, Firebase Auth, etc.)
- * @return An {@code ApiFuture} which will complete successfully with the created Firebase Custom
- * Token, or unsuccessfully with the failure Exception.
+ * (Realtime Database, Firebase Auth, etc.). Should be less than 128 characters.
+ * @return An {@code ApiFuture} which will complete successfully with the created Firebase custom
+ * token, or unsuccessfully with the failure Exception.
+ * @throws IllegalArgumentException If the specified uid is null or empty, or if the app has not
+ * been initialized with service account credentials.
*/
- public ApiFuture createCustomTokenAsync(String uid) {
- return new TaskToApiFuture<>(createCustomToken(uid));
+ public ApiFuture createCustomTokenAsync(@NonNull String uid) {
+ return createCustomTokenAsync(uid, null);
}
/**
- * Creates a Firebase Custom Token associated with the given UID and additionally containing the
- * specified developerClaims. This token can then be provided back to a client application for use
- * with the signInWithCustomToken authentication API.
+ * Similar to {@link #createCustomToken(String, Map)} but performs the operation
+ * asynchronously.
*
* @param uid The UID to store in the token. This identifies the user to other Firebase services
* (Realtime Database, Storage, etc.). Should be less than 128 characters.
* @param developerClaims Additional claims to be stored in the token (and made available to
* security rules in Database, Storage, etc.). These must be able to be serialized to JSON
* (e.g. contain only Maps, Arrays, Strings, Booleans, Numbers, etc.)
- * @return An {@code ApiFuture} which will complete successfully with the created Firebase Custom
- * Token, or unsuccessfully with the failure Exception.
+ * @return An {@code ApiFuture} which will complete successfully with the created Firebase custom
+ * token, or unsuccessfully with the failure Exception.
+ * @throws IllegalArgumentException If the specified uid is null or empty, or if the app has not
+ * been initialized with service account credentials.
*/
public ApiFuture createCustomTokenAsync(
+ @NonNull String uid, @Nullable Map developerClaims) {
+ return createCustomTokenOp(uid, developerClaims).callAsync(firebaseApp);
+ }
+
+ private CallableOperation createCustomTokenOp(
final String uid, final Map developerClaims) {
- return new TaskToApiFuture<>(createCustomToken(uid, developerClaims));
+ checkNotDestroyed();
+ checkArgument(!Strings.isNullOrEmpty(uid), "uid must not be null or empty");
+ checkArgument(credentials instanceof ServiceAccountCredentials,
+ "Must initialize FirebaseApp with a service account credential to call "
+ + "createCustomToken()");
+ return new CallableOperation() {
+ @Override
+ public String execute() throws FirebaseAuthException {
+ final ServiceAccountCredentials serviceAccount = (ServiceAccountCredentials) credentials;
+ FirebaseTokenFactory tokenFactory = FirebaseTokenFactory.getInstance();
+ try {
+ return tokenFactory.createSignedCustomAuthTokenForUser(
+ uid,
+ developerClaims,
+ serviceAccount.getClientEmail(),
+ serviceAccount.getPrivateKey());
+ } catch (GeneralSecurityException | IOException e) {
+ throw new FirebaseAuthException(ERROR_CUSTOM_TOKEN,
+ "Failed to generate a custom token", e);
+ }
+ }
+ };
}
/**
- * Similar to {@link #verifyIdTokenAsync(String)}, but returns a {@link Task}.
+ * Parses and verifies a Firebase ID Token.
*
- * @param token A Firebase ID Token to verify and parse.
- * @return A {@link Task} which will complete successfully with the parsed token, or
- * unsuccessfully with the failure Exception.
- * @deprecated Use {@link #verifyIdTokenAsync(String)}
+ * A Firebase application can identify itself to a trusted backend server by sending its
+ * Firebase ID Token (accessible via the {@code getToken} API in the Firebase Authentication
+ * client) with its requests. The backend server can then use the {@code verifyIdToken()} method
+ * to verify that the token is valid. This method ensures that the token is correctly signed,
+ * has not expired, and it was issued to the Firebase project associated with this
+ * {@link FirebaseAuth} instance.
+ *
+ *
This method does not check whether a token has been revoked. Use
+ * {@link #verifyIdToken(String, boolean)} to perform an additional revocation check.
+ *
+ * @param token A Firebase ID token string to parse and verify.
+ * @return A {@link FirebaseToken} representing the verified and decoded token.
+ * @throws IllegalArgumentException If the token is null, empty, or if the {@link FirebaseApp}
+ * instance does not have a project ID associated with it.
+ * @throws FirebaseAuthException If an error occurs while parsing or validating the token.
*/
- public Task verifyIdToken(final String token) {
+ public FirebaseToken verifyIdToken(@NonNull String token) throws FirebaseAuthException {
return verifyIdToken(token, false);
}
-
- private Task verifyIdToken(final String token, final boolean checkRevoked) {
+
+ /**
+ * Parses and verifies a Firebase ID Token.
+ *
+ * A Firebase application can identify itself to a trusted backend server by sending its
+ * Firebase ID Token (accessible via the {@code getToken} API in the Firebase Authentication
+ * client) with its requests. The backend server can then use the {@code verifyIdToken()} method
+ * to verify that the token is valid. This method ensures that the token is correctly signed,
+ * has not expired, and it was issued to the Firebase project associated with this
+ * {@link FirebaseAuth} instance.
+ *
+ *
If {@code checkRevoked} is set to true, this method performs an additional check to see
+ * if the ID token has been revoked since it was issues. This requires making an additional
+ * remote API call.
+ *
+ * @param token A Firebase ID token string to parse and verify.
+ * @param checkRevoked A boolean denoting whether to check if the tokens were revoked.
+ * @return A {@link FirebaseToken} representing the verified and decoded token.
+ * @throws IllegalArgumentException If the token is null, empty, or if the {@link FirebaseApp}
+ * instance does not have a project ID associated with it.
+ * @throws FirebaseAuthException If an error occurs while parsing or validating the token.
+ */
+ public FirebaseToken verifyIdToken(
+ @NonNull String token, boolean checkRevoked) throws FirebaseAuthException {
+ return verifyIdTokenOp(token, checkRevoked).call();
+ }
+
+ /**
+ * Similar to {@link #verifyIdToken(String)} but performs the operation asynchronously.
+ *
+ * @param token A Firebase ID Token to verify and parse.
+ * @return An {@code ApiFuture} which will complete successfully with the parsed token, or
+ * unsuccessfully with a {@link FirebaseAuthException}.
+ * @throws IllegalArgumentException If the token is null, empty, or if the {@link FirebaseApp}
+ * instance does not have a project ID associated with it.
+ */
+ public ApiFuture verifyIdTokenAsync(@NonNull String token) {
+ return verifyIdTokenAsync(token, false);
+ }
+
+ /**
+ * Similar to {@link #verifyIdToken(String, boolean)} but performs the operation asynchronously.
+ *
+ * @param token A Firebase ID Token to verify and parse.
+ * @param checkRevoked A boolean denoting whether to check if the tokens were revoked.
+ * @return An {@code ApiFuture} which will complete successfully with the parsed token, or
+ * unsuccessfully with a {@link FirebaseAuthException}.
+ * @throws IllegalArgumentException If the token is null, empty, or if the {@link FirebaseApp}
+ * instance does not have a project ID associated with it.
+ */
+ public ApiFuture verifyIdTokenAsync(@NonNull String token, boolean checkRevoked) {
+ return verifyIdTokenOp(token, checkRevoked).callAsync(firebaseApp);
+ }
+
+ private CallableOperation verifyIdTokenOp(
+ final String token, final boolean checkRevoked) {
checkNotDestroyed();
- checkState(!Strings.isNullOrEmpty(projectId),
+ checkArgument(!Strings.isNullOrEmpty(token), "ID token must not be null or empty");
+ checkArgument(!Strings.isNullOrEmpty(projectId),
"Must initialize FirebaseApp with a project ID to call verifyIdToken()");
- return call(new Callable() {
+ return new CallableOperation() {
@Override
- public FirebaseToken call() throws Exception {
+ protected FirebaseToken execute() throws FirebaseAuthException {
FirebaseTokenVerifier firebaseTokenVerifier =
FirebaseTokenVerifier.createIdTokenVerifier(projectId, keyManagers, clock);
- FirebaseToken firebaseToken = FirebaseToken.parse(jsonFactory, token);
+ FirebaseToken firebaseToken;
+ try {
+ firebaseToken = FirebaseToken.parse(jsonFactory, token);
+ } catch (IOException e) {
+ throw new FirebaseAuthException(ERROR_INVALID_ID_TOKEN, "Failed to parse token", e);
+ }
+
// This will throw a FirebaseAuthException with details on how the token is invalid.
firebaseTokenVerifier.verifyTokenAndSignature(firebaseToken.getToken());
@@ -320,122 +464,69 @@ public FirebaseToken call() throws Exception {
}
return firebaseToken;
}
- });
- }
-
- private Task revokeRefreshTokens(String uid) {
- checkNotDestroyed();
- long currentTimeSeconds = System.currentTimeMillis() / 1000L;
- final UpdateRequest request = new UpdateRequest(uid).setValidSince(currentTimeSeconds);
- return call(new Callable() {
- @Override
- public Void call() throws Exception {
- userManager.updateUser(request, jsonFactory);
- return null;
- }
- });
+ };
}
/**
* Revokes all refresh tokens for the specified user.
- *
+ *
* Updates the user's tokensValidAfterTimestamp to the current UTC time expressed in
* milliseconds since the epoch and truncated to 1 second accuracy. It is important that the
* server on which this is called has its clock set correctly and synchronized.
- *
+ *
*
While this will revoke all sessions for a specified user and disable any new ID tokens for
* existing sessions from getting minted, existing ID tokens may remain active until their
- * natural expiration (one hour).
+ * natural expiration (one hour).
* To verify that ID tokens are revoked, use {@link #verifyIdTokenAsync(String, boolean)}.
- *
+ *
* @param uid The user id for which tokens are revoked.
- * @return An {@code ApiFuture} which will complete successfully or if updating the user fails,
- * unsuccessfully with the failure Exception.
+ * @throws IllegalArgumentException If the user ID is null or empty.
+ * @throws FirebaseAuthException If an error occurs while revoking tokens.
*/
- public ApiFuture revokeRefreshTokensAsync(String uid) {
- return new TaskToApiFuture<>(revokeRefreshTokens(uid));
+ public void revokeRefreshTokens(@NonNull String uid) throws FirebaseAuthException {
+ revokeRefreshTokensOp(uid).call();
}
/**
- * Parses and verifies a Firebase ID Token.
- *
- * A Firebase application can identify itself to a trusted backend server by sending its
- * Firebase ID Token (accessible via the getToken API in the Firebase Authentication client) with
- * its request.
- *
- *
The backend server can then use the verifyIdToken() method to verify the token is valid,
- * meaning: the token is properly signed, has not expired, and it was issued for the project
- * associated with this FirebaseAuth instance (which by default is extracted from your service
- * account)
- *
- *
If the token is valid, the returned Future will complete successfully and provide a
- * parsed version of the token from which the UID and other claims in the token can be inspected.
- * If the token is invalid, the future throws an exception indicating the failure.
+ * Similar to {@link #revokeRefreshTokens(String)} but performs the operation asynchronously.
*
- *
This does not check whether a token has been revoked.
- * See {@link #verifyIdTokenAsync(String, boolean)} below.
- *
- * @param token A Firebase ID Token to verify and parse.
- * @return An {@code ApiFuture} which will complete successfully with the parsed token, or
- * unsuccessfully with the failure Exception.
+ * @param uid The user id for which tokens are revoked.
+ * @return An {@code ApiFuture} which will complete successfully or fail with a
+ * {@link FirebaseAuthException} in the event of an error.
+ * @throws IllegalArgumentException If the user ID is null or empty.
*/
- public ApiFuture verifyIdTokenAsync(final String token) {
- return verifyIdTokenAsync(token, false);
+ public ApiFuture revokeRefreshTokensAsync(@NonNull String uid) {
+ return revokeRefreshTokensOp(uid).callAsync(firebaseApp);
}
- /**
- * Parses and verifies a Firebase ID Token and if requested, checks whether it was revoked.
- *
- * A Firebase application can identify itself to a trusted backend server by sending its
- * Firebase ID Token (accessible via the getToken API in the Firebase Authentication client) with
- * its request.
- *
- *
The backend server can then use the verifyIdToken() method to verify the token is valid,
- * meaning: the token is properly signed, has not expired, and it was issued for the project
- * associated with this FirebaseAuth instance (which by default is extracted from your service
- * account)
- *
- *
If {@code checkRevoked} is true, additionally checks if the token has been revoked.
- *
- *
If the token is valid, and not revoked, the returned Future will complete successfully and
- * provide a parsed version of the token from which the UID and other claims in the token can be
- * inspected.
- * If the token is invalid or has been revoked, the future throws an exception indicating the
- * failure.
- *
- * @param token A Firebase ID Token to verify and parse.
- * @param checkRevoked A boolean indicating whether to check if the tokens were revoked.
- * @return An {@code ApiFuture} which will complete successfully with the parsed token, or
- * unsuccessfully with the failure Exception.
- */
- public ApiFuture verifyIdTokenAsync(final String token,
- final boolean checkRevoked) {
- return new TaskToApiFuture<>(verifyIdToken(token, checkRevoked));
+ private CallableOperation revokeRefreshTokensOp(final String uid) {
+ checkNotDestroyed();
+ checkArgument(!Strings.isNullOrEmpty(uid), "uid must not be null or empty");
+ return new CallableOperation() {
+ @Override
+ protected Void execute() throws FirebaseAuthException {
+ int currentTimeSeconds = (int) (System.currentTimeMillis() / 1000);
+ UpdateRequest request = new UpdateRequest(uid).setValidSince(currentTimeSeconds);
+ userManager.updateUser(request, jsonFactory);
+ return null;
+ }
+ };
}
/**
- * Similar to {@link #getUserAsync(String)}, but returns a {@link Task}.
+ * Gets the user data corresponding to the specified user ID.
*
* @param uid A user ID string.
- * @return A {@link Task} which will complete successfully with a {@link UserRecord} instance.
- * If an error occurs while retrieving user data or if the specified user ID does not exist,
- * the task fails with a {@link FirebaseAuthException}.
+ * @return A {@link UserRecord} instance.
* @throws IllegalArgumentException If the user ID string is null or empty.
- * @deprecated Use {@link #getUserAsync(String)}
+ * @throws FirebaseAuthException If an error occurs while retrieving user data.
*/
- public Task getUser(final String uid) {
- checkNotDestroyed();
- checkArgument(!Strings.isNullOrEmpty(uid), "uid must not be null or empty");
- return call(new Callable() {
- @Override
- public UserRecord call() throws Exception {
- return userManager.getUserById(uid);
- }
- });
+ public UserRecord getUser(@NonNull String uid) throws FirebaseAuthException {
+ return getUserOp(uid).call();
}
/**
- * Gets the user data corresponding to the specified user ID.
+ * Similar to {@link #getUser(String)} but performs the operation asynchronously.
*
* @param uid A user ID string.
* @return An {@code ApiFuture} which will complete successfully with a {@link UserRecord}
@@ -443,33 +534,35 @@ public UserRecord call() throws Exception {
* not exist, the future throws a {@link FirebaseAuthException}.
* @throws IllegalArgumentException If the user ID string is null or empty.
*/
- public ApiFuture getUserAsync(final String uid) {
- return new TaskToApiFuture<>(getUser(uid));
+ public ApiFuture getUserAsync(@NonNull String uid) {
+ return getUserOp(uid).callAsync(firebaseApp);
+ }
+
+ private CallableOperation getUserOp(final String uid) {
+ checkNotDestroyed();
+ checkArgument(!Strings.isNullOrEmpty(uid), "uid must not be null or empty");
+ return new CallableOperation() {
+ @Override
+ protected UserRecord execute() throws FirebaseAuthException {
+ return userManager.getUserById(uid);
+ }
+ };
}
/**
- * Similar to {@link #getUserByEmailAsync(String)}, but returns a {@link Task}.
+ * Gets the user data corresponding to the specified user email.
*
* @param email A user email address string.
- * @return A {@link Task} which will complete successfully with a {@link UserRecord} instance.
- * If an error occurs while retrieving user data or if the email address does not correspond
- * to a user, the task fails with a {@link FirebaseAuthException}.
+ * @return A {@link UserRecord} instance.
* @throws IllegalArgumentException If the email is null or empty.
- * @deprecated Use {@link #getUserByEmailAsync(String)}
+ * @throws FirebaseAuthException If an error occurs while retrieving user data.
*/
- public Task getUserByEmail(final String email) {
- checkNotDestroyed();
- checkArgument(!Strings.isNullOrEmpty(email), "email must not be null or empty");
- return call(new Callable() {
- @Override
- public UserRecord call() throws Exception {
- return userManager.getUserByEmail(email);
- }
- });
+ public UserRecord getUserByEmail(@NonNull String email) throws FirebaseAuthException {
+ return getUserByEmailOp(email).call();
}
/**
- * Gets the user data corresponding to the specified user email.
+ * Similar to {@link #getUserByEmail(String)} but performs the operation asynchronously.
*
* @param email A user email address string.
* @return An {@code ApiFuture} which will complete successfully with a {@link UserRecord}
@@ -477,29 +570,32 @@ public UserRecord call() throws Exception {
* correspond to a user, the future throws a {@link FirebaseAuthException}.
* @throws IllegalArgumentException If the email is null or empty.
*/
- public ApiFuture getUserByEmailAsync(final String email) {
- return new TaskToApiFuture<>(getUserByEmail(email));
+ public ApiFuture getUserByEmailAsync(@NonNull String email) {
+ return getUserByEmailOp(email).callAsync(firebaseApp);
+ }
+
+ private CallableOperation getUserByEmailOp(
+ final String email) {
+ checkNotDestroyed();
+ checkArgument(!Strings.isNullOrEmpty(email), "email must not be null or empty");
+ return new CallableOperation() {
+ @Override
+ protected UserRecord execute() throws FirebaseAuthException {
+ return userManager.getUserByEmail(email);
+ }
+ };
}
/**
- * Similar to {@link #getUserByPhoneNumberAsync(String)}, but returns a {@link Task}.
+ * Gets the user data corresponding to the specified user phone number.
*
* @param phoneNumber A user phone number string.
- * @return A {@link Task} which will complete successfully with a {@link UserRecord} instance.
- * If an error occurs while retrieving user data or if the phone number does not
- * correspond to a user, the task fails with a {@link FirebaseAuthException}.
+ * @return A a {@link UserRecord} instance.
* @throws IllegalArgumentException If the phone number is null or empty.
- * @deprecated Use {@link #getUserByPhoneNumberAsync(String)}
+ * @throws FirebaseAuthException If an error occurs while retrieving user data.
*/
- public Task getUserByPhoneNumber(final String phoneNumber) {
- checkNotDestroyed();
- checkArgument(!Strings.isNullOrEmpty(phoneNumber), "phone number must not be null or empty");
- return call(new Callable() {
- @Override
- public UserRecord call() throws Exception {
- return userManager.getUserByPhoneNumber(phoneNumber);
- }
- });
+ public UserRecord getUserByPhoneNumber(@NonNull String phoneNumber) throws FirebaseAuthException {
+ return getUserByPhoneNumberOp(phoneNumber).call();
}
/**
@@ -511,20 +607,20 @@ public UserRecord call() throws Exception {
* correspond to a user, the future throws a {@link FirebaseAuthException}.
* @throws IllegalArgumentException If the phone number is null or empty.
*/
- public ApiFuture getUserByPhoneNumberAsync(final String phoneNumber) {
- return new TaskToApiFuture<>(getUserByPhoneNumber(phoneNumber));
+ public ApiFuture getUserByPhoneNumberAsync(@NonNull String phoneNumber) {
+ return getUserByPhoneNumberOp(phoneNumber).callAsync(firebaseApp);
}
- private Task listUsers(@Nullable String pageToken, int maxResults) {
+ private CallableOperation getUserByPhoneNumberOp(
+ final String phoneNumber) {
checkNotDestroyed();
- final PageFactory factory = new PageFactory(
- new DefaultUserSource(userManager, jsonFactory), maxResults, pageToken);
- return call(new Callable() {
+ checkArgument(!Strings.isNullOrEmpty(phoneNumber), "phone number must not be null or empty");
+ return new CallableOperation() {
@Override
- public ListUsersPage call() throws Exception {
- return factory.create();
+ protected UserRecord execute() throws FirebaseAuthException {
+ return userManager.getUserByPhoneNumber(phoneNumber);
}
- });
+ };
}
/**
@@ -532,6 +628,34 @@ public ListUsersPage call() throws Exception {
* limited to 1000 users.
*
* @param pageToken A non-empty page token string, or null to retrieve the first page of users.
+ * @return A {@link ListUsersPage} instance.
+ * @throws IllegalArgumentException If the specified page token is empty.
+ * @throws FirebaseAuthException If an error occurs while retrieving user data.
+ */
+ public ListUsersPage listUsers(@Nullable String pageToken) throws FirebaseAuthException {
+ return listUsers(pageToken, FirebaseUserManager.MAX_LIST_USERS_RESULTS);
+ }
+
+ /**
+ * Gets a page of users starting from the specified {@code pageToken}.
+ *
+ * @param pageToken A non-empty page token string, or null to retrieve the first page of users.
+ * @param maxResults Maximum number of users to include in the returned page. This may not
+ * exceed 1000.
+ * @return A {@link ListUsersPage} instance.
+ * @throws IllegalArgumentException If the specified page token is empty, or max results value
+ * is invalid.
+ * @throws FirebaseAuthException If an error occurs while retrieving user data.
+ */
+ public ListUsersPage listUsers(
+ @Nullable String pageToken, int maxResults) throws FirebaseAuthException {
+ return listUsersOp(pageToken, maxResults).call();
+ }
+
+ /**
+ * Similar to {@link #listUsers(String)} but performs the operation asynchronously.
+ *
+ * @param pageToken A non-empty page token string, or null to retrieve the first page of users.
* @return An {@code ApiFuture} which will complete successfully with a {@link ListUsersPage}
* instance. If an error occurs while retrieving user data, the future throws an exception.
* @throws IllegalArgumentException If the specified page token is empty.
@@ -541,7 +665,7 @@ public ApiFuture listUsersAsync(@Nullable String pageToken) {
}
/**
- * Gets a page of users starting from the specified {@code pageToken}.
+ * Similar to {@link #listUsers(String, int)} but performs the operation asynchronously.
*
* @param pageToken A non-empty page token string, or null to retrieve the first page of users.
* @param maxResults Maximum number of users to include in the returned page. This may not
@@ -551,30 +675,22 @@ public ApiFuture listUsersAsync(@Nullable String pageToken) {
* @throws IllegalArgumentException If the specified page token is empty, or max results value
* is invalid.
*/
- public ApiFuture listUsersAsync(@Nullable String pageToken, int maxResults) {
- return new TaskToApiFuture<>(listUsers(pageToken, maxResults));
+ public ApiFuture listUsersAsync(
+ @Nullable final String pageToken, final int maxResults) {
+ return listUsersOp(pageToken, maxResults).callAsync(firebaseApp);
}
- /**
- * Similar to {@link #createUserAsync(CreateRequest)}, but returns a {@link Task}.
- *
- * @param request A non-null {@link CreateRequest} instance.
- * @return A {@link Task} which will complete successfully with a {@link UserRecord} instance
- * corresponding to the newly created account. If an error occurs while creating the user
- * account, the task fails with a {@link FirebaseAuthException}.
- * @throws NullPointerException if the provided request is null.
- * @deprecated Use {@link #createUserAsync(CreateRequest)}
- */
- public Task createUser(final CreateRequest request) {
+ private CallableOperation listUsersOp(
+ @Nullable String pageToken, int maxResults) {
checkNotDestroyed();
- checkNotNull(request, "create request must not be null");
- return call(new Callable() {
+ final PageFactory factory = new PageFactory(
+ new DefaultUserSource(userManager, jsonFactory), maxResults, pageToken);
+ return new CallableOperation() {
@Override
- public UserRecord call() throws Exception {
- String uid = userManager.createUser(request);
- return userManager.getUserById(uid);
+ protected ListUsersPage execute() throws FirebaseAuthException {
+ return factory.create();
}
- });
+ };
}
/**
@@ -582,61 +698,77 @@ public UserRecord call() throws Exception {
* {@link CreateRequest}.
*
* @param request A non-null {@link CreateRequest} instance.
+ * @return A {@link UserRecord} instance corresponding to the newly created account.
+ * @throws NullPointerException if the provided request is null.
+ * @throws FirebaseAuthException if an error occurs while creating the user account.
+ */
+ public UserRecord createUser(@NonNull CreateRequest request) throws FirebaseAuthException {
+ return createUserOp(request).call();
+ }
+
+ /**
+ * Similar to {@link #createUser(CreateRequest)} but performs the operation asynchronously.
+ *
+ * @param request A non-null {@link CreateRequest} instance.
* @return An {@code ApiFuture} which will complete successfully with a {@link UserRecord}
* instance corresponding to the newly created account. If an error occurs while creating the
* user account, the future throws a {@link FirebaseAuthException}.
* @throws NullPointerException if the provided request is null.
*/
- public ApiFuture createUserAsync(final CreateRequest request) {
- return new TaskToApiFuture<>(createUser(request));
+ public ApiFuture createUserAsync(@NonNull CreateRequest request) {
+ return createUserOp(request).callAsync(firebaseApp);
+ }
+
+ private CallableOperation createUserOp(
+ final CreateRequest request) {
+ checkNotDestroyed();
+ checkNotNull(request, "create request must not be null");
+ return new CallableOperation() {
+ @Override
+ protected UserRecord execute() throws FirebaseAuthException {
+ String uid = userManager.createUser(request);
+ return userManager.getUserById(uid);
+ }
+ };
}
/**
- * Similar to {@link #updateUserAsync(UpdateRequest)}, but returns a {@link Task}.
+ * Updates an existing user account with the attributes contained in the specified
+ * {@link UpdateRequest}.
*
* @param request A non-null {@link UpdateRequest} instance.
- * @return A {@link Task} which will complete successfully with a {@link UserRecord} instance
- * corresponding to the updated user account. If an error occurs while updating the user
+ * @return A {@link UserRecord} instance corresponding to the updated user account.
* account, the task fails with a {@link FirebaseAuthException}.
* @throws NullPointerException if the provided update request is null.
- * @deprecated Use {@link #updateUserAsync(UpdateRequest)}
+ * @throws FirebaseAuthException if an error occurs while updating the user account.
*/
- public Task updateUser(final UpdateRequest request) {
- checkNotDestroyed();
- checkNotNull(request, "update request must not be null");
- return call(new Callable() {
- @Override
- public UserRecord call() throws Exception {
- userManager.updateUser(request, jsonFactory);
- return userManager.getUserById(request.getUid());
- }
- });
+ public UserRecord updateUser(@NonNull UpdateRequest request) throws FirebaseAuthException {
+ return updateUserOp(request).call();
}
/**
- * Updates an existing user account with the attributes contained in the specified
- * {@link UpdateRequest}.
+ * Similar to {@link #updateUser(UpdateRequest)} but performs the operation asynchronously.
*
* @param request A non-null {@link UpdateRequest} instance.
* @return An {@code ApiFuture} which will complete successfully with a {@link UserRecord}
* instance corresponding to the updated user account. If an error occurs while updating the
* user account, the future throws a {@link FirebaseAuthException}.
- * @throws NullPointerException if the provided update request is null.
*/
- public ApiFuture updateUserAsync(final UpdateRequest request) {
- return new TaskToApiFuture<>(updateUser(request));
+ public ApiFuture updateUserAsync(@NonNull UpdateRequest request) {
+ return updateUserOp(request).callAsync(firebaseApp);
}
- private Task setCustomClaims(String uid, Map claims) {
+ private CallableOperation updateUserOp(
+ final UpdateRequest request) {
checkNotDestroyed();
- final UpdateRequest request = new UpdateRequest(uid).setCustomClaims(claims);
- return call(new Callable() {
+ checkNotNull(request, "update request must not be null");
+ return new CallableOperation() {
@Override
- public Void call() throws Exception {
+ protected UserRecord execute() throws FirebaseAuthException {
userManager.updateUser(request, jsonFactory);
- return null;
+ return userManager.getUserById(request.getUid());
}
- });
+ };
}
/**
@@ -646,53 +778,78 @@ public Void call() throws Exception {
*
* @param uid A user ID string.
* @param claims A map of custom claims or null.
- * @return An {@code ApiFuture} which will complete successfully when the user account has been
- * updated. If an error occurs while deleting the user account, the future throws a
- * {@link FirebaseAuthException}.
+ * @throws FirebaseAuthException If an error occurs while updating custom claims.
* @throws IllegalArgumentException If the user ID string is null or empty, or the claims
* payload is invalid or too large.
*/
- public ApiFuture setCustomUserClaimsAsync(String uid, Map claims) {
- return new TaskToApiFuture<>(setCustomClaims(uid, claims));
+ public void setCustomClaims(@NonNull String uid,
+ @Nullable Map claims) throws FirebaseAuthException {
+ setCustomUserClaimsOp(uid, claims).call();
}
/**
- * Similar to {@link #deleteUserAsync(String)}, but returns a {@link Task}.
+ * Similar to {@link #setCustomClaims(String, Map)} but performs the operation asynchronously.
*
* @param uid A user ID string.
- * @return A {@link Task} which will complete successfully when the specified user account has
- * been deleted. If an error occurs while deleting the user account, the task fails with a
+ * @param claims A map of custom claims or null.
+ * @return An {@code ApiFuture} which will complete successfully when the user account has been
+ * updated. If an error occurs while deleting the user account, the future throws a
* {@link FirebaseAuthException}.
* @throws IllegalArgumentException If the user ID string is null or empty.
- * @deprecated Use {@link #deleteUserAsync(String)}
*/
- public Task deleteUser(final String uid) {
+ public ApiFuture setCustomUserClaimsAsync(
+ @NonNull String uid, @Nullable Map claims) {
+ return setCustomUserClaimsOp(uid, claims).callAsync(firebaseApp);
+ }
+
+ private CallableOperation setCustomUserClaimsOp(
+ final String uid, final Map claims) {
checkNotDestroyed();
checkArgument(!Strings.isNullOrEmpty(uid), "uid must not be null or empty");
- return call(new Callable() {
+ return new CallableOperation() {
@Override
- public Void call() throws Exception {
- userManager.deleteUser(uid);
+ protected Void execute() throws FirebaseAuthException {
+ final UpdateRequest request = new UpdateRequest(uid).setCustomClaims(claims);
+ userManager.updateUser(request, jsonFactory);
return null;
}
- });
+ };
}
/**
* Deletes the user identified by the specified user ID.
*
* @param uid A user ID string.
+ * @throws IllegalArgumentException If the user ID string is null or empty.
+ * @throws FirebaseAuthException If an error occurs while deleting the user.
+ */
+ public void deleteUser(@NonNull String uid) throws FirebaseAuthException {
+ deleteUserOp(uid).call();
+ }
+
+ /**
+ * Similar to {@link #deleteUser(String)} but performs the operation asynchronously.
+ *
+ * @param uid A user ID string.
* @return An {@code ApiFuture} which will complete successfully when the specified user account
* has been deleted. If an error occurs while deleting the user account, the future throws a
* {@link FirebaseAuthException}.
* @throws IllegalArgumentException If the user ID string is null or empty.
*/
public ApiFuture deleteUserAsync(final String uid) {
- return new TaskToApiFuture<>(deleteUser(uid));
+ return deleteUserOp(uid).callAsync(firebaseApp);
}
- private Task call(Callable command) {
- return ImplFirebaseTrampolines.submitCallable(firebaseApp, command);
+ private CallableOperation deleteUserOp(final String uid) {
+ checkNotDestroyed();
+ checkArgument(!Strings.isNullOrEmpty(uid), "uid must not be null or empty");
+ return new CallableOperation() {
+ @Override
+ protected Void execute() throws FirebaseAuthException {
+ userManager.deleteUser(uid);
+ return null;
+ }
+ };
}
@VisibleForTesting
diff --git a/src/main/java/com/google/firebase/auth/FirebaseCredential.java b/src/main/java/com/google/firebase/auth/FirebaseCredential.java
deleted file mode 100644
index b238d299c..000000000
--- a/src/main/java/com/google/firebase/auth/FirebaseCredential.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.firebase.auth;
-
-import com.google.firebase.tasks.Task;
-
-/**
- * Provides Google OAuth2 access tokens used to authenticate with Firebase services. In most cases,
- * you will not need to implement this yourself and can instead use the default implementations
- * provided by {@link FirebaseCredentials}.
- *
- * @deprecated Use {@code GoogleCredentials}.
- */
-public interface FirebaseCredential {
-
- /**
- * Returns a Google OAuth2 access token which can be used to authenticate with Firebase services.
- * This method does not cache tokens, and therefore each invocation will fetch a fresh token.
- * The caller is expected to implement caching by referencing the token expiry details
- * available in the returned GoogleOAuthAccessToken instance.
- *
- * @return A {@link Task} providing a Google OAuth access token.
- */
- Task getAccessToken();
-}
diff --git a/src/main/java/com/google/firebase/auth/FirebaseCredentials.java b/src/main/java/com/google/firebase/auth/FirebaseCredentials.java
deleted file mode 100644
index 4ae1d62da..000000000
--- a/src/main/java/com/google/firebase/auth/FirebaseCredentials.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.firebase.auth;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.api.client.googleapis.util.Utils;
-import com.google.api.client.http.HttpTransport;
-import com.google.api.client.json.JsonFactory;
-import com.google.auth.http.HttpTransportFactory;
-import com.google.auth.oauth2.GoogleCredentials;
-import com.google.auth.oauth2.ServiceAccountCredentials;
-import com.google.auth.oauth2.UserCredentials;
-import com.google.common.base.Strings;
-import com.google.firebase.auth.internal.BaseCredential;
-import com.google.firebase.internal.NonNull;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Standard {@link FirebaseCredential} implementations for use with {@link
- * com.google.firebase.FirebaseOptions}.
- *
- * @deprecated Use {@code GoogleCredentials}.
- */
-public class FirebaseCredentials {
-
- private FirebaseCredentials() {
- }
-
- /**
- * Returns a {@link FirebaseCredential} based on Google Application Default Credentials which can
- * be used to authenticate the SDK.
- *
- * See Google
- * Application Default Credentials for details on Google Application Deafult Credentials.
- *
- *
See Initialize the SDK for code samples
- * and detailed documentation.
- *
- * @return A {@link FirebaseCredential} based on Google Application Default Credentials which can
- * be used to authenticate the SDK.
- */
- @NonNull
- public static FirebaseCredential applicationDefault() {
- return DefaultCredentialsHolder.INSTANCE;
- }
-
- /**
- * Returns a {@link FirebaseCredential} based on Google Application Default Credentials which can
- * be used to authenticate the SDK. Allows specifying the HttpTransport and the
- * JsonFactory to be used when communicating with the remote authentication server.
- *
- *
See Google
- * Application Default Credentials for details on Google Application Deafult Credentials.
- *
- *
See Initialize the SDK for code samples
- * and detailed documentation.
- *
- * @param transport HttpTransport used to communicate with the remote
- * authentication server.
- * @param jsonFactory JsonFactory used to parse JSON responses from the remote
- * authentication server.
- * @return A {@link FirebaseCredential} based on Google Application Default Credentials which can
- * be used to authenticate the SDK.
- */
- @NonNull
- public static FirebaseCredential applicationDefault(
- HttpTransport transport, JsonFactory jsonFactory) {
- try {
- return new ApplicationDefaultCredential(transport);
- } catch (IOException e) {
- // To prevent a breaking API change, we throw an unchecked exception.
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Returns a {@link FirebaseCredential} generated from the provided service account certificate
- * which can be used to authenticate the SDK.
- *
- *
See Initialize the SDK for code samples
- * and detailed documentation.
- *
- * @param serviceAccount An InputStream containing the JSON representation of a
- * service account certificate.
- * @return A {@link FirebaseCredential} generated from the provided service account certificate
- * which can be used to authenticate the SDK.
- * @throws IOException If an error occurs while parsing the service account certificate.
- */
- @NonNull
- public static FirebaseCredential fromCertificate(InputStream serviceAccount) throws IOException {
- return fromCertificate(serviceAccount, Utils.getDefaultTransport(),
- Utils.getDefaultJsonFactory());
- }
-
- /**
- * Returns a {@link FirebaseCredential} generated from the provided service account certificate
- * which can be used to authenticate the SDK. Allows specifying the HttpTransport
- * and the JsonFactory to be used when communicating with the remote authentication
- * server.
- *
- *
See Initialize the SDK for code samples
- * and detailed documentation.
- *
- * @param serviceAccount An InputStream containing the JSON representation of a
- * service account certificate.
- * @param transport HttpTransport used to communicate with the remote
- * authentication server.
- * @param jsonFactory JsonFactory used to parse JSON responses from the remote
- * authentication server.
- * @return A {@link FirebaseCredential} generated from the provided service account certificate
- * which can be used to authenticate the SDK.
- * @throws IOException If an error occurs while parsing the service account certificate.
- */
- @NonNull
- public static FirebaseCredential fromCertificate(InputStream serviceAccount,
- HttpTransport transport, JsonFactory jsonFactory) throws IOException {
- ServiceAccountCredentials credentials = ServiceAccountCredentials.fromStream(
- serviceAccount, wrap(transport));
- checkArgument(!Strings.isNullOrEmpty(credentials.getProjectId()),
- "Failed to parse service account: 'project_id' must be set");
- return new CertCredential(credentials);
- }
-
- /**
- * Returns a {@link FirebaseCredential} generated from the provided refresh token which can be
- * used to authenticate the SDK.
- *
- *
See Initialize the SDK for code samples
- * and detailed documentation.
- *
- * @param refreshToken An InputStream containing the JSON representation of a refresh
- * token.
- * @return A {@link FirebaseCredential} generated from the provided service account credential
- * which can be used to authenticate the SDK.
- * @throws IOException If an error occurs while parsing the refresh token.
- */
- @NonNull
- public static FirebaseCredential fromRefreshToken(InputStream refreshToken) throws IOException {
- return fromRefreshToken(
- refreshToken, Utils.getDefaultTransport(), Utils.getDefaultJsonFactory());
- }
-
- /**
- * Returns a {@link FirebaseCredential} generated from the provided refresh token which can be
- * used to authenticate the SDK. Allows specifying the HttpTransport and the
- * JsonFactory to be used when communicating with the remote authentication server.
- *
- *
See Initialize the SDK for code samples
- * and detailed documentation.
- *
- * @param refreshToken An InputStream containing the JSON representation of a refresh
- * token.
- * @param transport HttpTransport used to communicate with the remote
- * authentication server.
- * @param jsonFactory JsonFactory used to parse JSON responses from the remote
- * authentication server.
- * @return A {@link FirebaseCredential} generated from the provided service account credential
- * which can be used to authenticate the SDK.
- * @throws IOException If an error occurs while parsing the refresh token.
- */
- @NonNull
- public static FirebaseCredential fromRefreshToken(final InputStream refreshToken,
- HttpTransport transport, JsonFactory jsonFactory) throws IOException {
- return new RefreshTokenCredential(refreshToken, transport);
- }
-
- static class CertCredential extends BaseCredential {
-
- CertCredential(ServiceAccountCredentials credentials) throws IOException {
- super(credentials);
- }
- }
-
- static class ApplicationDefaultCredential extends BaseCredential {
-
- ApplicationDefaultCredential(HttpTransport transport) throws IOException {
- super(GoogleCredentials.getApplicationDefault(wrap(transport)));
- }
- }
-
- static class RefreshTokenCredential extends BaseCredential {
-
- RefreshTokenCredential(InputStream inputStream, HttpTransport transport) throws IOException {
- super(UserCredentials.fromStream(inputStream, wrap(transport)));
- }
- }
-
- private static class DefaultCredentialsHolder {
-
- static final FirebaseCredential INSTANCE =
- applicationDefault(Utils.getDefaultTransport(), Utils.getDefaultJsonFactory());
- }
-
- private static HttpTransportFactory wrap(final HttpTransport transport) {
- checkNotNull(transport, "HttpTransport must not be null");
- return new HttpTransportFactory() {
- @Override
- public HttpTransport create() {
- return transport;
- }
- };
- }
-}
diff --git a/src/main/java/com/google/firebase/auth/GoogleOAuthAccessToken.java b/src/main/java/com/google/firebase/auth/GoogleOAuthAccessToken.java
deleted file mode 100644
index 85e6021e3..000000000
--- a/src/main/java/com/google/firebase/auth/GoogleOAuthAccessToken.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.firebase.auth;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.base.Strings;
-
-/**
- * Represents an OAuth access token, which can be used to access Firebase and other qualified
- * Google APIs. Encapsulates both the token string, and its expiration time.
- *
- * @deprecated Use GoogleCredentials and associated classes.
- */
-public class GoogleOAuthAccessToken {
-
-
- private final String accessToken;
- private final long expiryTime;
-
- /**
- * Create a new GoogleOAuthAccessToken instance
- *
- * @param accessToken JWT access token string
- * @param expiryTime Time at which the token will expire (milliseconds since epoch)
- * @throws IllegalArgumentException If the token is null or empty
- */
- public GoogleOAuthAccessToken(String accessToken, long expiryTime) {
- checkArgument(!Strings.isNullOrEmpty(accessToken), "Access token must not be null");
- this.accessToken = accessToken;
- this.expiryTime = expiryTime;
- }
-
- /**
- * Returns the JWT access token.
- */
- public String getAccessToken() {
- return accessToken;
- }
-
- /**
- * Returns the expiration time as a milliseconds since epoch timestamp.
- */
- public long getExpiryTime() {
- return expiryTime;
- }
-
-}
diff --git a/src/main/java/com/google/firebase/auth/internal/BaseCredential.java b/src/main/java/com/google/firebase/auth/internal/BaseCredential.java
deleted file mode 100644
index d15832a55..000000000
--- a/src/main/java/com/google/firebase/auth/internal/BaseCredential.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.firebase.auth.internal;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.auth.oauth2.AccessToken;
-import com.google.auth.oauth2.GoogleCredentials;
-import com.google.common.collect.ImmutableList;
-import com.google.firebase.auth.FirebaseCredential;
-import com.google.firebase.auth.GoogleOAuthAccessToken;
-import com.google.firebase.tasks.Task;
-import com.google.firebase.tasks.Tasks;
-
-import java.io.IOException;
-import java.util.List;
-
-/**
- * Internal base class for built-in FirebaseCredential implementations.
- */
-public abstract class BaseCredential implements FirebaseCredential {
-
- public static final List FIREBASE_SCOPES =
- ImmutableList.of(
- // Enables access to Firebase Realtime Database.
- "https://www.googleapis.com/auth/firebase.database",
-
- // Enables access to the email address associated with a project.
- "https://www.googleapis.com/auth/userinfo.email",
-
- // Enables access to Google Identity Toolkit (for user management APIs).
- "https://www.googleapis.com/auth/identitytoolkit",
-
- // Enables access to Google Cloud Storage.
- "https://www.googleapis.com/auth/devstorage.full_control",
-
- // Enables access to Google Cloud Firestore
- "https://www.googleapis.com/auth/cloud-platform",
- "https://www.googleapis.com/auth/datastore");
-
- private final GoogleCredentials googleCredentials;
-
- public BaseCredential(GoogleCredentials googleCredentials) {
- this.googleCredentials = checkNotNull(googleCredentials).createScoped(FIREBASE_SCOPES);
- }
-
- public final GoogleCredentials getGoogleCredentials() {
- return googleCredentials;
- }
-
- @Override
- public Task getAccessToken() {
- try {
- AccessToken accessToken = googleCredentials.refreshAccessToken();
- GoogleOAuthAccessToken googleToken = new GoogleOAuthAccessToken(accessToken.getTokenValue(),
- accessToken.getExpirationTime().getTime());
- return Tasks.forResult(googleToken);
- } catch (Exception e) {
- return Tasks.forException(e);
- }
- }
-
-}
diff --git a/src/main/java/com/google/firebase/auth/internal/FirebaseCredentialsAdapter.java b/src/main/java/com/google/firebase/auth/internal/FirebaseCredentialsAdapter.java
deleted file mode 100644
index e1b069eda..000000000
--- a/src/main/java/com/google/firebase/auth/internal/FirebaseCredentialsAdapter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.firebase.auth.internal;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.auth.oauth2.AccessToken;
-import com.google.auth.oauth2.GoogleCredentials;
-import com.google.firebase.auth.FirebaseCredential;
-import com.google.firebase.auth.GoogleOAuthAccessToken;
-import com.google.firebase.tasks.Tasks;
-import java.io.IOException;
-import java.util.Date;
-import java.util.concurrent.ExecutionException;
-
-/**
- * An adapter for converting custom {@link FirebaseCredential} implementations into
- * GoogleCredentials.
- */
-public final class FirebaseCredentialsAdapter extends GoogleCredentials {
-
- private final FirebaseCredential credential;
-
- public FirebaseCredentialsAdapter(FirebaseCredential credential) {
- this.credential = checkNotNull(credential);
- }
-
- @Override
- public AccessToken refreshAccessToken() throws IOException {
- try {
- GoogleOAuthAccessToken token = Tasks.await(credential.getAccessToken());
- return new AccessToken(token.getAccessToken(), new Date(token.getExpiryTime()));
- } catch (ExecutionException | InterruptedException e) {
- throw new IOException("Error while obtaining OAuth2 token", e);
- }
- }
-}
diff --git a/src/main/java/com/google/firebase/database/ChildEventListener.java b/src/main/java/com/google/firebase/database/ChildEventListener.java
index 1a1bb24d1..65bcdfdce 100644
--- a/src/main/java/com/google/firebase/database/ChildEventListener.java
+++ b/src/main/java/com/google/firebase/database/ChildEventListener.java
@@ -53,7 +53,7 @@ public interface ChildEventListener {
/**
* This method is triggered when a child location's priority changes. See {@link
- * DatabaseReference#setPriority(Object)} and Ordered Data for more information on priorities and ordering data.
*
diff --git a/src/main/java/com/google/firebase/database/DataSnapshot.java b/src/main/java/com/google/firebase/database/DataSnapshot.java
index 700fa2a2a..f1f470505 100644
--- a/src/main/java/com/google/firebase/database/DataSnapshot.java
+++ b/src/main/java/com/google/firebase/database/DataSnapshot.java
@@ -38,7 +38,7 @@
* They are efficiently-generated immutable copies of the data at a Firebase Database location. They
* can't be modified and will never change. To modify data at a location, use a {@link
* DatabaseReference DatabaseReference} reference (e.g. with {@link
- * DatabaseReference#setValue(Object)}).
+ * DatabaseReference#setValueAsync(Object)}).
*/
public class DataSnapshot {
@@ -114,7 +114,7 @@ public boolean exists() {
* List<Object>
*
*
- * This list is recursive; the possible types for {@link java.lang.Object} in the above list
+ *
This list is recursive; the possible types for Object in the above list
* is given by the same list. These types correspond to the types available in JSON.
*
* @return The data contained in this snapshot as native types or null if there is no data at this
@@ -138,7 +138,7 @@ public Object getValue() {
*
List<Object>
*
*
- * This list is recursive; the possible types for {@link java.lang.Object} in the above list is
+ *
This list is recursive; the possible types for Object in the above list is
* given by the same list. These types correspond to the types available in JSON.
*
*
If useExportFormat is set to true, priority information will be included in the output.
@@ -206,7 +206,7 @@ public T getValue(Class valueType) {
/**
* Due to the way that Java implements generics, it takes an extra step to get back a
- * properly-typed Collection. So, in the case where you want a {@link java.util.List} of Message
+ * properly-typed Collection. So, in the case where you want a List of Message
* instances, you will need to do something like the following:
*
*
diff --git a/src/main/java/com/google/firebase/database/DatabaseReference.java b/src/main/java/com/google/firebase/database/DatabaseReference.java
index 1c1b9db71..10dfe40ba 100644
--- a/src/main/java/com/google/firebase/database/DatabaseReference.java
+++ b/src/main/java/com/google/firebase/database/DatabaseReference.java
@@ -33,8 +33,6 @@
import com.google.firebase.database.utilities.Utilities;
import com.google.firebase.database.utilities.Validation;
import com.google.firebase.database.utilities.encoding.CustomClassMapper;
-import com.google.firebase.internal.TaskToApiFuture;
-import com.google.firebase.tasks.Task;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
@@ -177,7 +175,7 @@ public DatabaseReference push() {
* @return The ApiFuture for this operation.
*/
public ApiFuture setValueAsync(Object value) {
- return new TaskToApiFuture<>(setValue(value));
+ return setValueInternal(value, PriorityUtilities.parsePriority(this.path, null), null);
}
/**
@@ -215,29 +213,6 @@ public ApiFuture setValueAsync(Object value) {
* @return The ApiFuture for this operation.
*/
public ApiFuture setValueAsync(Object value, Object priority) {
- return new TaskToApiFuture<>(setValue(value, priority));
- }
-
- /**
- * Similar to {@link #setValueAsync(Object)} but returns a Task.
- *
- * @param value The value to set at this location
- * @return The {@link Task} for this operation.
- * @deprecated Use {@link #setValueAsync(Object)}
- */
- public Task setValue(Object value) {
- return setValueInternal(value, PriorityUtilities.parsePriority(this.path, null), null);
- }
-
- /**
- * Similar to {@link #setValueAsync(Object, Object)} but returns a Task.
- *
- * @param value The value to set at this location
- * @param priority The priority to set at this location
- * @return The {@link Task} for this operation.
- * @deprecated Use {@link #setValueAsync(Object, Object)}
- */
- public Task setValue(Object value, Object priority) {
return setValueInternal(value, PriorityUtilities.parsePriority(this.path, priority), null);
}
@@ -315,13 +290,14 @@ public void setValue(Object value, Object priority, CompletionListener listener)
setValueInternal(value, PriorityUtilities.parsePriority(this.path, priority), listener);
}
- private Task setValueInternal(Object value, Node priority, CompletionListener optListener) {
+ private ApiFuture setValueInternal(Object value, Node priority, CompletionListener
+ optListener) {
Validation.validateWritablePath(getPath());
ValidationPath.validateWithObject(getPath(), value);
Object bouncedValue = CustomClassMapper.convertToPlainJavaTypes(value);
Validation.validateWritableObject(bouncedValue);
final Node node = NodeUtilities.NodeFromJSON(bouncedValue, priority);
- final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
+ final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
repo.scheduleNow(
new Runnable() {
@Override
@@ -364,17 +340,6 @@ public void run() {
* @return The ApiFuture for this operation.
*/
public ApiFuture setPriorityAsync(Object priority) {
- return new TaskToApiFuture<>(setPriority(priority));
- }
-
- /**
- * Similar to {@link #setPriorityAsync(Object)} but returns a Task.
- *
- * @param priority The priority to set at the specified location.
- * @return The {@link Task} for this operation.
- * @deprecated Use {@link #setPriorityAsync(Object)}
- */
- public Task setPriority(Object priority) {
return setPriorityInternal(PriorityUtilities.parsePriority(this.path, priority), null);
}
@@ -413,10 +378,10 @@ public void setPriority(Object priority, CompletionListener listener) {
// Remove
- private Task setPriorityInternal(final Node priority, CompletionListener optListener) {
+ private ApiFuture setPriorityInternal(final Node priority, CompletionListener optListener) {
Validation.validateWritablePath(getPath());
- final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
+ final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
repo.scheduleNow(
new Runnable() {
@Override
@@ -438,17 +403,6 @@ public void run() {
* @return The ApiFuture for this operation.
*/
public ApiFuture updateChildrenAsync(Map update) {
- return new TaskToApiFuture<>(updateChildren(update));
- }
-
- /**
- * Similar to {@link #updateChildrenAsync(Map)} but returns a Task.
- *
- * @param update The paths to update and their new values
- * @return The {@link Task} for this operation.
- * @deprecated Use {@link #updateChildrenAsync(Map)}
- */
- public Task updateChildren(Map update) {
return updateChildrenInternal(update, null);
}
@@ -467,7 +421,7 @@ public void updateChildren(final Map update, final CompletionLis
// Transactions
- private Task updateChildrenInternal(
+ private ApiFuture updateChildrenInternal(
final Map update, final CompletionListener optListener) {
if (update == null) {
throw new NullPointerException("Can't pass null for argument 'update' in updateChildren()");
@@ -477,7 +431,7 @@ private Task updateChildrenInternal(
Validation.parseAndValidateUpdate(getPath(), bouncedUpdate);
final CompoundWrite merge = CompoundWrite.fromPathMerge(parsedUpdate);
- final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
+ final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
repo.scheduleNow(
new Runnable() {
@Override
@@ -494,17 +448,7 @@ public void run() {
* @return The ApiFuture for this operation.
*/
public ApiFuture removeValueAsync() {
- return new TaskToApiFuture<>(removeValue());
- }
-
- /**
- * Similar to {@link #removeValueAsync()} but returns a Task.
- *
- * @return The Task for this operation.
- * @deprecated Use {@link #removeValueAsync()}
- */
- public Task removeValue() {
- return setValue(null);
+ return setValueAsync(null);
}
// Manual Connection Management
diff --git a/src/main/java/com/google/firebase/database/FirebaseDatabase.java b/src/main/java/com/google/firebase/database/FirebaseDatabase.java
index 6a196f913..2ddb55d58 100644
--- a/src/main/java/com/google/firebase/database/FirebaseDatabase.java
+++ b/src/main/java/com/google/firebase/database/FirebaseDatabase.java
@@ -256,24 +256,6 @@ public void goOffline() {
RepoManager.interrupt(ensureRepo());
}
- /**
- * By default, this is set to {@link Logger.Level#INFO INFO}. This includes any internal errors
- * ({@link Logger.Level#ERROR ERROR}) and any security debug messages ({@link Logger.Level#INFO
- * INFO}) that the client receives. Set to {@link Logger.Level#DEBUG DEBUG} to turn on the
- * diagnostic logging, and {@link Logger.Level#NONE NONE} to disable all logging.
- *
- * @param logLevel The desired minimum log level
- * @deprecated This method will be removed in a future release. Use SLF4J-based logging instead.
- * For example, add the slf4j-simple.jar to the classpath to log to STDERR. See
- * SLF4J user manual for more details.
- */
- public synchronized void setLogLevel(Logger.Level logLevel) {
- synchronized (lock) {
- assertUnfrozen("setLogLevel");
- this.config.setLogLevel(logLevel);
- }
- }
-
/**
* The Firebase Database client will cache synchronized data and keep track of all writes you've
* initiated while your application is running. It seamlessly handles intermittent network
diff --git a/src/main/java/com/google/firebase/database/MutableData.java b/src/main/java/com/google/firebase/database/MutableData.java
index 79e87f2b4..7a0e7983b 100644
--- a/src/main/java/com/google/firebase/database/MutableData.java
+++ b/src/main/java/com/google/firebase/database/MutableData.java
@@ -177,7 +177,7 @@ public String getKey() {
* List<Object>
*
*
- * This list is recursive; the possible types for {@link java.lang.Object} in the above list is
+ *
This list is recursive; the possible types for Object in the above list is
* given by the same list. These types correspond to the types available in JSON.
*
* @return The data contained in this instance as native types, or null if there is no data at
@@ -190,7 +190,7 @@ public Object getValue() {
/**
* Due to the way that Java implements generics, it takes an extra step to get back a
- * properly-typed Collection. So, in the case where you want a {@link java.util.List} of Message
+ * properly-typed Collection. So, in the case where you want a List of Message
* instances, you will need to do something like the following:
*
*
diff --git a/src/main/java/com/google/firebase/database/OnDisconnect.java b/src/main/java/com/google/firebase/database/OnDisconnect.java
index 3b02987db..7b4cc0859 100644
--- a/src/main/java/com/google/firebase/database/OnDisconnect.java
+++ b/src/main/java/com/google/firebase/database/OnDisconnect.java
@@ -28,8 +28,6 @@
import com.google.firebase.database.utilities.Utilities;
import com.google.firebase.database.utilities.Validation;
import com.google.firebase.database.utilities.encoding.CustomClassMapper;
-import com.google.firebase.internal.TaskToApiFuture;
-import com.google.firebase.tasks.Task;
import java.util.Map;
@@ -52,41 +50,6 @@ public class OnDisconnect {
this.path = path;
}
- /**
- * Similar to {@link #setValueAsync(Object)}, but returns a Task.
- *
- * @param value The value to be set when a disconnect occurs
- * @return The {@link Task} for this operation.
- * @deprecated Use {@link #setValueAsync(Object)}
- */
- public Task setValue(Object value) {
- return onDisconnectSetInternal(value, PriorityUtilities.NullPriority(), null);
- }
-
- /**
- * Similar to {@link #setValueAsync(Object, String)}, but returns a Task.
- *
- * @param value The value to be set when a disconnect occurs
- * @param priority The priority to be set when a disconnect occurs
- * @return The {@link Task} for this operation.
- * @deprecated Use {@link #setValueAsync(Object, String)}
- */
- public Task setValue(Object value, String priority) {
- return onDisconnectSetInternal(value, PriorityUtilities.parsePriority(path, priority), null);
- }
-
- /**
- * Similar to {@link #setValueAsync(Object, double)}, but returns a Task.
- *
- * @param value The value to be set when a disconnect occurs
- * @param priority The priority to be set when a disconnect occurs
- * @return The {@link Task} for this operation.
- * @deprecated Use {@link #setValueAsync(Object, double)}
- */
- public Task setValue(Object value, double priority) {
- return onDisconnectSetInternal(value, PriorityUtilities.parsePriority(path, priority), null);
- }
-
/**
* Ensure the data at this location is set to the specified value when the client is disconnected
* (due to closing the browser, navigating to a new page, or network issues).
@@ -157,7 +120,7 @@ public void setValue(Object value, Map priority, CompletionListener listener) {
* @return The ApiFuture for this operation.
*/
public ApiFuture setValueAsync(Object value) {
- return new TaskToApiFuture<>(setValue(value));
+ return onDisconnectSetInternal(value, PriorityUtilities.NullPriority(), null);
}
/**
@@ -172,7 +135,7 @@ public ApiFuture setValueAsync(Object value) {
* @return The ApiFuture for this operation.
*/
public ApiFuture setValueAsync(Object value, String priority) {
- return new TaskToApiFuture<>(setValue(value, priority));
+ return onDisconnectSetInternal(value, PriorityUtilities.parsePriority(path, priority), null);
}
/**
@@ -187,17 +150,17 @@ public ApiFuture setValueAsync(Object value, String priority) {
* @return The ApiFuture for this operation.
*/
public ApiFuture setValueAsync(Object value, double priority) {
- return new TaskToApiFuture<>(setValue(value, priority));
+ return onDisconnectSetInternal(value, PriorityUtilities.parsePriority(path, priority), null);
}
- private Task onDisconnectSetInternal(
+ private ApiFuture onDisconnectSetInternal(
Object value, Node priority, final CompletionListener optListener) {
Validation.validateWritablePath(path);
ValidationPath.validateWithObject(path, value);
Object bouncedValue = CustomClassMapper.convertToPlainJavaTypes(value);
Validation.validateWritableObject(bouncedValue);
final Node node = NodeUtilities.NodeFromJSON(bouncedValue, priority);
- final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
+ final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
repo.scheduleNow(
new Runnable() {
@Override
@@ -210,17 +173,6 @@ public void run() {
// Update
- /**
- * Similar to {@link #updateChildrenAsync(Map)}, but returns a Task.
- *
- * @param update The paths to update, along with their desired values
- * @return The {@link Task} for this operation.
- * @deprecated Use {@link #updateChildrenAsync(Map)}
- */
- public Task updateChildren(Map update) {
- return updateChildrenInternal(update, null);
- }
-
/**
* Ensure the data has the specified child values updated when the client is disconnected
*
@@ -238,13 +190,13 @@ public void updateChildren(final Map update, final CompletionLis
* @return The ApiFuture for this operation.
*/
public ApiFuture updateChildrenAsync(Map update) {
- return new TaskToApiFuture<>(updateChildren(update));
+ return updateChildrenInternal(update, null);
}
- private Task updateChildrenInternal(
+ private ApiFuture updateChildrenInternal(
final Map update, final CompletionListener optListener) {
final Map parsedUpdate = Validation.parseAndValidateUpdate(path, update);
- final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
+ final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
repo.scheduleNow(
new Runnable() {
@Override
@@ -257,16 +209,6 @@ public void run() {
// Remove
- /**
- * Similar to {@link #removeValueAsync()}, but returns a Task.
- *
- * @return The {@link Task} for this operation.
- * @deprecated Use {@link #removeValueAsync()}
- */
- public Task removeValue() {
- return setValue(null);
- }
-
/**
* Remove the value at this location when the client disconnects
*
@@ -282,21 +224,11 @@ public void removeValue(CompletionListener listener) {
* @return The ApiFuture for this operation.
*/
public ApiFuture removeValueAsync() {
- return new TaskToApiFuture<>(removeValue());
+ return setValueAsync(null);
}
// Cancel the operation
- /**
- * Similar to {@link #cancelAsync()} ()}, but returns a Task.
- *
- * @return The {@link Task} for this operation.
- * @deprecated Use {@link #cancelAsync()}.
- */
- public Task cancel() {
- return cancelInternal(null);
- }
-
/**
* Cancel any disconnect operations that are queued up at this location
*
@@ -312,11 +244,11 @@ public void cancel(final CompletionListener listener) {
* @return The ApiFuture for this operation.
*/
public ApiFuture cancelAsync() {
- return new TaskToApiFuture<>(cancel());
+ return cancelInternal(null);
}
- private Task cancelInternal(final CompletionListener optListener) {
- final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
+ private ApiFuture cancelInternal(final CompletionListener optListener) {
+ final Pair, CompletionListener> wrapped = Utilities.wrapOnComplete(optListener);
repo.scheduleNow(
new Runnable() {
@Override
diff --git a/src/main/java/com/google/firebase/database/connection/Connection.java b/src/main/java/com/google/firebase/database/connection/Connection.java
index 4059e46e8..83e377304 100644
--- a/src/main/java/com/google/firebase/database/connection/Connection.java
+++ b/src/main/java/com/google/firebase/database/connection/Connection.java
@@ -17,10 +17,11 @@
package com.google.firebase.database.connection;
import com.google.common.annotations.VisibleForTesting;
-import com.google.firebase.database.logging.LogWrapper;
import java.util.HashMap;
import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
class Connection implements WebsocketConnection.Delegate {
@@ -39,11 +40,14 @@ class Connection implements WebsocketConnection.Delegate {
private static final String SERVER_HELLO_TIMESTAMP = "ts";
private static final String SERVER_HELLO_HOST = "h";
private static final String SERVER_HELLO_SESSION_ID = "s";
+
+ private static final Logger logger = LoggerFactory.getLogger(Connection.class);
+
private static long connectionIds = 0;
- private final LogWrapper logger;
private final HostInfo hostInfo;
private final Delegate delegate;
+ private final String label;
private WebsocketConnection conn;
private State state;
@@ -54,36 +58,31 @@ class Connection implements WebsocketConnection.Delegate {
String cachedHost,
Delegate delegate,
String optLastSessionId) {
- this(context, hostInfo, delegate,
+ this(hostInfo, delegate,
new DefaultWebsocketConnectionFactory(context, hostInfo, cachedHost, optLastSessionId));
}
@VisibleForTesting
Connection(
- ConnectionContext context,
HostInfo hostInfo,
Delegate delegate,
WebsocketConnectionFactory connFactory) {
long connId = connectionIds++;
this.hostInfo = hostInfo;
this.delegate = delegate;
- this.logger = new LogWrapper(context.getLogger(), Connection.class, "conn_" + connId);
+ this.label = "[conn_" + connId + "]";
this.state = State.REALTIME_CONNECTING;
this.conn = connFactory.newConnection(this);
}
public void open() {
- if (logger.logsDebug()) {
- logger.debug("Opening a connection");
- }
+ logger.debug("{} Opening a connection", label);
conn.open();
}
public void close(DisconnectReason reason) {
if (state != State.REALTIME_DISCONNECTED) {
- if (logger.logsDebug()) {
- logger.debug("closing realtime connection");
- }
+ logger.debug("{} Closing realtime connection", label);
state = State.REALTIME_DISCONNECTED;
if (conn != null) {
@@ -123,21 +122,14 @@ public void onMessage(Map message) {
Map data = (Map) message.get(SERVER_ENVELOPE_DATA);
onControlMessage(data);
} else {
- if (logger.logsDebug()) {
- logger.debug("Ignoring unknown server message type: " + messageType);
- }
+ logger.debug("{} Ignoring unknown server message type: {}", label, messageType);
}
} else {
- if (logger.logsDebug()) {
- logger.debug(
- "Failed to parse server message: missing message type:" + message.toString());
- }
+ logger.debug("{} Failed to parse server message: missing message type: {}", label, message);
close();
}
} catch (ClassCastException e) {
- if (logger.logsDebug()) {
- logger.debug("Failed to parse server message: " + e.toString());
- }
+ logger.debug("{} Failed to parse server message", label, e);
close();
}
}
@@ -146,30 +138,22 @@ public void onMessage(Map message) {
public void onDisconnect(boolean wasEverConnected) {
conn = null;
if (!wasEverConnected && state == State.REALTIME_CONNECTING) {
- if (logger.logsDebug()) {
- logger.debug("Realtime connection failed");
- }
+ logger.debug("{} Realtime connection failed", label);
} else {
- if (logger.logsDebug()) {
- logger.debug("Realtime connection lost");
- }
+ logger.debug("{} Realtime connection lost", label);
}
close();
}
private void onDataMessage(Map data) {
- if (logger.logsDebug()) {
- logger.debug("received data message: " + data.toString());
- }
+ logger.debug("{} Received data message: {}", label, data);
// We don't do anything with data messages, just kick them up a level
delegate.onDataMessage(data);
}
private void onControlMessage(Map data) {
- if (logger.logsDebug()) {
- logger.debug("Got control message: " + data.toString());
- }
+ logger.debug("{} Got control message: {}", label, data);
try {
String messageType = (String) data.get(SERVER_CONTROL_MESSAGE_TYPE);
if (messageType != null) {
@@ -185,28 +169,20 @@ private void onControlMessage(Map data) {
(Map) data.get(SERVER_CONTROL_MESSAGE_DATA);
onHandshake(handshakeData);
} else {
- if (logger.logsDebug()) {
- logger.debug("Ignoring unknown control message: " + messageType);
- }
+ logger.debug("{} Ignoring unknown control message: {}", label, messageType);
}
} else {
- if (logger.logsDebug()) {
- logger.debug("Got invalid control message: " + data.toString());
- }
+ logger.debug("{} Got invalid control message: {}", label, data);
close();
}
} catch (ClassCastException e) {
- if (logger.logsDebug()) {
- logger.debug("Failed to parse control message: " + e.toString());
- }
+ logger.debug("{} Failed to parse control message", label, e);
close();
}
}
private void onConnectionShutdown(String reason) {
- if (logger.logsDebug()) {
- logger.debug("Connection shutdown command received. Shutting down...");
- }
+ logger.debug("{} Connection shutdown command received. Shutting down...", label);
delegate.onKill(reason);
close();
}
@@ -224,21 +200,15 @@ private void onHandshake(Map handshake) {
}
private void onConnectionReady(long timestamp, String sessionId) {
- if (logger.logsDebug()) {
- logger.debug("realtime connection established");
- }
+ logger.debug("{} Realtime connection established", label);
state = State.REALTIME_CONNECTED;
delegate.onReady(timestamp, sessionId);
}
private void onReset(String host) {
- if (logger.logsDebug()) {
- logger.debug(
- "Got a reset; killing connection to "
- + this.hostInfo.getHost()
- + "; Updating internalHost to "
- + host);
- }
+ logger.debug(
+ "{} Got a reset; killing connection to {}; Updating internalHost to {}",
+ label, hostInfo.getHost(), host);
delegate.onCacheHost(host);
// Explicitly close the connection with SERVER_RESET so calling code knows to reconnect
@@ -248,12 +218,12 @@ private void onReset(String host) {
private void sendData(Map data, boolean isSensitive) {
if (state != State.REALTIME_CONNECTED) {
- logger.debug("Tried to send on an unconnected connection");
+ logger.debug("{} Tried to send on an unconnected connection", label);
} else {
if (isSensitive) {
- logger.debug("Sending data (contents hidden)");
+ logger.debug("{} Sending data (contents hidden)", label);
} else {
- logger.debug("Sending data: %s", data);
+ logger.debug("{} Sending data: {}", label, data);
}
conn.send(data);
}
diff --git a/src/main/java/com/google/firebase/database/connection/ConnectionContext.java b/src/main/java/com/google/firebase/database/connection/ConnectionContext.java
index 03b4b45f4..574bc1df9 100644
--- a/src/main/java/com/google/firebase/database/connection/ConnectionContext.java
+++ b/src/main/java/com/google/firebase/database/connection/ConnectionContext.java
@@ -16,8 +16,6 @@
package com.google.firebase.database.connection;
-import com.google.firebase.database.logging.Logger;
-
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
@@ -25,21 +23,18 @@ public class ConnectionContext {
private final ScheduledExecutorService executorService;
private final ConnectionAuthTokenProvider authTokenProvider;
- private final Logger logger;
private final boolean persistenceEnabled;
private final String clientSdkVersion;
private final String userAgent;
private final ThreadFactory threadFactory;
public ConnectionContext(
- Logger logger,
ConnectionAuthTokenProvider authTokenProvider,
ScheduledExecutorService executorService,
boolean persistenceEnabled,
String clientSdkVersion,
String userAgent,
ThreadFactory threadFactory) {
- this.logger = logger;
this.authTokenProvider = authTokenProvider;
this.executorService = executorService;
this.persistenceEnabled = persistenceEnabled;
@@ -48,10 +43,6 @@ public ConnectionContext(
this.threadFactory = threadFactory;
}
- public Logger getLogger() {
- return this.logger;
- }
-
public ConnectionAuthTokenProvider getAuthTokenProvider() {
return this.authTokenProvider;
}
diff --git a/src/main/java/com/google/firebase/database/connection/NettyWebSocketClient.java b/src/main/java/com/google/firebase/database/connection/NettyWebSocketClient.java
index 40d172722..9769b65a8 100644
--- a/src/main/java/com/google/firebase/database/connection/NettyWebSocketClient.java
+++ b/src/main/java/com/google/firebase/database/connection/NettyWebSocketClient.java
@@ -5,8 +5,7 @@
import static com.google.common.base.Preconditions.checkState;
import com.google.common.base.Strings;
-import com.google.firebase.internal.GaeThreadFactory;
-import com.google.firebase.internal.RevivingScheduledExecutor;
+import com.google.firebase.internal.FirebaseScheduledExecutor;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
@@ -67,8 +66,8 @@ class NettyWebSocketClient implements WebsocketConnection.WSClient {
this.uri = checkNotNull(uri, "uri must not be null");
this.eventHandler = checkNotNull(eventHandler, "event handler must not be null");
this.channelHandler = new WebSocketClientHandler(uri, userAgent, eventHandler);
- this.executorService = new RevivingScheduledExecutor(
- threadFactory, "firebase-websocket-worker", GaeThreadFactory.isAvailable());
+ this.executorService = new FirebaseScheduledExecutor(threadFactory,
+ "firebase-websocket-worker");
this.group = new NioEventLoopGroup(1, this.executorService);
}
@@ -104,7 +103,7 @@ protected void initChannel(SocketChannel ch) {
channelFuture.addListener(
new ChannelFutureListener() {
@Override
- public void operationComplete(ChannelFuture future) throws Exception {
+ public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
eventHandler.onError(future.cause());
}
@@ -174,7 +173,7 @@ public void channelInactive(ChannelHandlerContext context) {
}
@Override
- public void channelRead0(ChannelHandlerContext context, Object message) throws Exception {
+ public void channelRead0(ChannelHandlerContext context, Object message) {
Channel channel = context.channel();
if (message instanceof FullHttpResponse) {
checkState(!handshaker.isHandshakeComplete());
diff --git a/src/main/java/com/google/firebase/database/connection/PersistentConnectionImpl.java b/src/main/java/com/google/firebase/database/connection/PersistentConnectionImpl.java
index 5f2f71303..fc79b4cfe 100644
--- a/src/main/java/com/google/firebase/database/connection/PersistentConnectionImpl.java
+++ b/src/main/java/com/google/firebase/database/connection/PersistentConnectionImpl.java
@@ -19,7 +19,6 @@
import static com.google.firebase.database.connection.ConnectionUtils.hardAssert;
import com.google.firebase.database.connection.util.RetryHelper;
-import com.google.firebase.database.logging.LogWrapper;
import com.google.firebase.database.util.GAuthToken;
import java.util.ArrayList;
@@ -33,6 +32,8 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class PersistentConnectionImpl implements Connection.Delegate, PersistentConnection {
@@ -91,6 +92,9 @@ public class PersistentConnectionImpl implements Connection.Delegate, Persistent
private static final String SERVER_KILL_INTERRUPT_REASON = "server_kill";
private static final String IDLE_INTERRUPT_REASON = "connection_idle";
private static final String TOKEN_REFRESH_INTERRUPT_REASON = "token_refresh";
+
+ private static final Logger logger = LoggerFactory.getLogger(PersistentConnection.class);
+
private static long connectionIds = 0;
private final Delegate delegate;
@@ -99,8 +103,8 @@ public class PersistentConnectionImpl implements Connection.Delegate, Persistent
private final ConnectionFactory connFactory;
private final ConnectionAuthTokenProvider authTokenProvider;
private final ScheduledExecutorService executorService;
- private final LogWrapper logger;
private final RetryHelper retryHelper;
+ private final String label;
private String cachedHost;
private HashSet interruptReasons = new HashSet<>();
@@ -143,7 +147,7 @@ public PersistentConnectionImpl(ConnectionContext context, HostInfo info, Delega
this.outstandingPuts = new HashMap<>();
this.onDisconnectRequestQueue = new ArrayList<>();
this.retryHelper =
- new RetryHelper.Builder(this.executorService, context.getLogger(), RetryHelper.class)
+ new RetryHelper.Builder(this.executorService, RetryHelper.class)
.withMinDelayAfterFailure(1000)
.withRetryExponent(1.3)
.withMaxDelay(30 * 1000)
@@ -151,7 +155,7 @@ public PersistentConnectionImpl(ConnectionContext context, HostInfo info, Delega
.build();
long connId = connectionIds++;
- this.logger = new LogWrapper(context.getLogger(), PersistentConnection.class, "pc_" + connId);
+ this.label = "[pc_" + connId + "]";
this.lastSessionId = null;
doIdleCheck();
}
@@ -159,9 +163,7 @@ public PersistentConnectionImpl(ConnectionContext context, HostInfo info, Delega
// Connection.Delegate methods
@Override
public void onReady(long timestamp, String sessionId) {
- if (logger.logsDebug()) {
- logger.debug("onReady");
- }
+ logger.debug("{} onReady", label);
lastConnectionEstablishedTime = System.currentTimeMillis();
handleTimestamp(timestamp);
@@ -188,16 +190,12 @@ public void listen(
Long tag,
RequestResultCallback listener) {
ListenQuerySpec query = new ListenQuerySpec(path, queryParams);
- if (logger.logsDebug()) {
- logger.debug("Listening on " + query);
- }
+ logger.debug("{} Listening on {}", label, query);
// TODO: Fix this somehow?
//hardAssert(query.isDefault() || !query.loadsAllData(), "listen() called for non-default but "
// + "complete query");
hardAssert(!listens.containsKey(query), "listen() called twice for same QuerySpec.");
- if (logger.logsDebug()) {
- logger.debug("Adding listen query: " + query);
- }
+ logger.debug("{} Adding listen query: {}", label, query);
OutstandingListen outstandingListen =
new OutstandingListen(listener, query, tag, currentHashFn);
listens.put(query, outstandingListen);
@@ -277,23 +275,19 @@ public void onDataMessage(Map message) {
Map body = (Map) message.get(SERVER_ASYNC_PAYLOAD);
onDataPush(action, body);
} else {
- if (logger.logsDebug()) {
- logger.debug("Ignoring unknown message: " + message);
- }
+ logger.debug("{} Ignoring unknown message: {}", label, message);
}
}
@Override
public void onDisconnect(Connection.DisconnectReason reason) {
- if (logger.logsDebug()) {
- logger.debug("Got on disconnect due to " + reason.name());
- }
+ logger.debug("{} Got on disconnect due to {}", label, reason.name());
this.connectionState = ConnectionState.Disconnected;
this.realtime = null;
this.hasOnDisconnects = false;
requestCBHash.clear();
if (inactivityTimer != null) {
- logger.debug("cancelling idle time checker");
+ logger.debug("{} Cancelling idle time checker", label);
inactivityTimer.cancel(false);
inactivityTimer = null;
}
@@ -319,21 +313,16 @@ public void onDisconnect(Connection.DisconnectReason reason) {
@Override
public void onKill(String reason) {
- if (logger.logsDebug()) {
- logger.debug(
- "Firebase Database connection was forcefully killed by the server. Will not attempt "
- + "reconnect. Reason: "
- + reason);
- }
+ logger.debug(
+ "{} Firebase Database connection was forcefully killed by the server. Will not attempt "
+ + "reconnect. Reason: {}", label, reason);
interrupt(SERVER_KILL_INTERRUPT_REASON);
}
@Override
public void unlisten(List path, Map queryParams) {
ListenQuerySpec query = new ListenQuerySpec(path, queryParams);
- if (logger.logsDebug()) {
- logger.debug("unlistening on " + query);
- }
+ logger.debug("{} Unlistening on {}", label, query);
// TODO: fix this by understanding query params?
//Utilities.hardAssert(query.isDefault() || !query.loadsAllData(),
@@ -395,9 +384,7 @@ public void onDisconnectCancel(List path, RequestResultCallback onComple
@Override
public void interrupt(String reason) {
- if (logger.logsDebug()) {
- logger.debug("Connection interrupted for: " + reason);
- }
+ logger.debug("{} Connection interrupted for: {}", label, reason);
interruptReasons.add(reason);
if (realtime != null) {
@@ -414,10 +401,7 @@ public void interrupt(String reason) {
@Override
public void resume(String reason) {
- if (logger.logsDebug()) {
- logger.debug("Connection no longer interrupted for: " + reason);
- }
-
+ logger.debug("{} Connection no longer interrupted for: {}", label, reason);
interruptReasons.remove(reason);
if (shouldReconnect() && connectionState == ConnectionState.Disconnected) {
@@ -444,7 +428,7 @@ public void refreshAuthToken() {
// we close the connection to make sure any writes/listens are queued until the connection
// is reauthed with the current token after reconnecting. Note that this will trigger
// onDisconnects which isn't ideal.
- logger.debug("Auth token refresh requested");
+ logger.debug("{} Auth token refresh requested", label);
// By using interrupt instead of closing the connection we make sure there are no race
// conditions with other fetch token attempts (interrupt/resume is expected to handle those
@@ -455,7 +439,7 @@ public void refreshAuthToken() {
@Override
public void refreshAuthToken(String token) {
- logger.debug("Auth token refreshed.");
+ logger.debug("{} Auth token refreshed.", label);
this.authToken = token;
if (connected()) {
if (token != null) {
@@ -473,13 +457,13 @@ private void tryScheduleReconnect() {
"Not in disconnected state: %s",
this.connectionState);
final boolean forceRefresh = this.forceAuthTokenRefresh;
- logger.debug("Scheduling connection attempt");
+ logger.debug("{} Scheduling connection attempt", label);
this.forceAuthTokenRefresh = false;
retryHelper.retry(
new Runnable() {
@Override
public void run() {
- logger.debug("Trying to fetch auth token");
+ logger.debug("{} Trying to fetch auth token", label);
hardAssert(
connectionState == ConnectionState.Disconnected,
"Not in disconnected state: %s",
@@ -496,7 +480,7 @@ public void onSuccess(String token) {
// Someone could have interrupted us while fetching the token,
// marking the connection as Disconnected
if (connectionState == ConnectionState.GettingToken) {
- logger.debug("Successfully fetched token, opening connection");
+ logger.debug("{} Successfully fetched token, opening connection", label);
openNetworkConnection(token);
} else {
hardAssert(
@@ -504,13 +488,13 @@ public void onSuccess(String token) {
"Expected connection state disconnected, but was %s",
connectionState);
logger.debug(
- "Not opening connection after token refresh, "
- + "because connection was set to disconnected");
+ "{} Not opening connection after token refresh, because connection "
+ + "was set to disconnected", label);
}
} else {
logger.debug(
- "Ignoring getToken result, because this was not the "
- + "latest attempt.");
+ "{} Ignoring getToken result, because this was not the "
+ + "latest attempt.", label);
}
}
@@ -518,12 +502,12 @@ public void onSuccess(String token) {
public void onError(String error) {
if (thisGetTokenAttempt == currentGetTokenAttempt) {
connectionState = ConnectionState.Disconnected;
- logger.debug("Error fetching token: " + error);
+ logger.debug("{} Error fetching token: {}", label, error);
tryScheduleReconnect();
} else {
logger.debug(
- "Ignoring getToken error, because this was not the "
- + "latest attempt.");
+ "{} Ignoring getToken error, because this was not the "
+ + "latest attempt.", label);
}
}
});
@@ -609,14 +593,10 @@ private void sendUnlisten(OutstandingListen listen) {
}
private OutstandingListen removeListen(ListenQuerySpec query) {
- if (logger.logsDebug()) {
- logger.debug("removing query " + query);
- }
+ logger.debug("{} removing query {}", label, query);
if (!listens.containsKey(query)) {
- if (logger.logsDebug()) {
- logger.debug(
- "Trying to remove listener for QuerySpec " + query + " but no listener exists.");
- }
+ logger.debug(
+ "{} Trying to remove listener for QuerySpec {} but no listener exists.", label, query);
return null;
} else {
OutstandingListen oldListen = listens.get(query);
@@ -627,9 +607,7 @@ private OutstandingListen removeListen(ListenQuerySpec query) {
}
private Collection removeListens(List path) {
- if (logger.logsDebug()) {
- logger.debug("removing all listens at path " + path);
- }
+ logger.debug("{} Removing all listens at path {}", label, path);
List removedListens = new ArrayList<>();
for (Map.Entry entry : listens.entrySet()) {
ListenQuerySpec query = entry.getKey();
@@ -649,9 +627,7 @@ private Collection removeListens(List path) {
}
private void onDataPush(String action, Map body) {
- if (logger.logsDebug()) {
- logger.debug("handleServerMessage: " + action + " " + body);
- }
+ logger.debug("{} handleServerMessage: {} {}", label, action, body);
if (action.equals(SERVER_ASYNC_DATA_UPDATE) || action.equals(SERVER_ASYNC_DATA_MERGE)) {
boolean isMerge = action.equals(SERVER_ASYNC_DATA_MERGE);
@@ -660,9 +636,7 @@ private void onDataPush(String action, Map body) {
Long tagNumber = ConnectionUtils.longFromObject(body.get(SERVER_DATA_TAG));
// ignore empty merges
if (isMerge && (payloadData instanceof Map) && ((Map) payloadData).size() == 0) {
- if (logger.logsDebug()) {
- logger.debug("ignoring empty merge for path " + pathString);
- }
+ logger.debug("{} Ignoring empty merge for path {}", label, pathString);
} else {
List path = ConnectionUtils.stringToPath(pathString);
delegate.onDataUpdate(path, payloadData, isMerge, tagNumber);
@@ -684,9 +658,7 @@ private void onDataPush(String action, Map body) {
rangeMerges.add(new RangeMerge(start, end, update));
}
if (rangeMerges.isEmpty()) {
- if (logger.logsDebug()) {
- logger.debug("Ignoring empty range merge for path " + pathString);
- }
+ logger.debug("{} Ignoring empty range merge for path {}", label, pathString);
} else {
this.delegate.onRangeMergeUpdate(path, rangeMerges, tag);
}
@@ -701,9 +673,7 @@ private void onDataPush(String action, Map body) {
} else if (action.equals(SERVER_ASYNC_SECURITY_DEBUG)) {
onSecurityDebugPacket(body);
} else {
- if (logger.logsDebug()) {
- logger.debug("Unrecognized action from server: " + action);
- }
+ logger.debug("{} Unrecognized action from server: {}", label, action);
}
}
@@ -723,7 +693,7 @@ private void onAuthRevoked(String errorCode, String errorMessage) {
// This might be for an earlier token than we just recently sent. But since we need to close
// the connection anyways, we can set it to null here and we will refresh the token later
// on reconnect.
- logger.debug("Auth token revoked: " + errorCode + " (" + errorMessage + ")");
+ logger.debug("{} Auth token revoked: {} ({})", label, errorCode, errorMessage);
this.authToken = null;
this.forceAuthTokenRefresh = true;
this.delegate.onAuthStatus(false);
@@ -733,7 +703,7 @@ private void onAuthRevoked(String errorCode, String errorMessage) {
private void onSecurityDebugPacket(Map message) {
// TODO: implement on iOS too
- logger.info((String) message.get("msg"));
+ logger.info("{} {}", label, message.get("msg"));
}
private void upgradeAuth() {
@@ -766,7 +736,7 @@ public void onResponse(Map response) {
forceAuthTokenRefresh = true;
delegate.onAuthStatus(false);
String reason = (String) response.get(SERVER_RESPONSE_DATA);
- logger.debug("Authentication failed: " + status + " (" + reason + ")");
+ logger.debug("{} Authentication failed: {} ({})", label, status, reason);
realtime.close();
if (status.equals("invalid_token") || status.equals("permission_denied")) {
@@ -778,11 +748,11 @@ public void onResponse(Map response) {
// Set a long reconnect delay because recovery is unlikely.
retryHelper.setMaxDelay();
logger.warn(
- "Provided authentication credentials are invalid. This "
+ "{} Provided authentication credentials are invalid. This "
+ "usually indicates your FirebaseApp instance was not initialized "
+ "correctly. Make sure your database URL is correct and that your "
+ "service account is for the correct project and is authorized to "
- + "access it.");
+ + "access it.", label);
}
}
}
@@ -814,9 +784,7 @@ private void sendUnauth() {
}
private void restoreAuth() {
- if (logger.logsDebug()) {
- logger.debug("calling restore state");
- }
+ logger.debug("{} Calling restore state", label);
hardAssert(
this.connectionState == ConnectionState.Connecting,
@@ -824,15 +792,11 @@ private void restoreAuth() {
this.connectionState);
if (authToken == null) {
- if (logger.logsDebug()) {
- logger.debug("Not restoring auth because token is null.");
- }
+ logger.debug("{} Not restoring auth because token is null.", label);
this.connectionState = ConnectionState.Connected;
restoreState();
} else {
- if (logger.logsDebug()) {
- logger.debug("Restoring auth.");
- }
+ logger.debug("{} Restoring auth.", label);
this.connectionState = ConnectionState.Authenticating;
sendAuthAndRestoreState();
}
@@ -845,19 +809,13 @@ private void restoreState() {
this.connectionState);
// Restore listens
- if (logger.logsDebug()) {
- logger.debug("Restoring outstanding listens");
- }
+ logger.debug("{} Restoring outstanding listens", label);
for (OutstandingListen listen : listens.values()) {
- if (logger.logsDebug()) {
- logger.debug("Restoring listen " + listen.getQuery());
- }
+ logger.debug("{} Restoring listen {}", label, listen.getQuery());
sendListen(listen);
}
- if (logger.logsDebug()) {
- logger.debug("Restoring writes.");
- }
+ logger.debug("{} Restoring writes.", label);
// Restore puts
ArrayList outstanding = new ArrayList<>(outstandingPuts.keySet());
// Make sure puts are restored in order
@@ -878,9 +836,7 @@ private void restoreState() {
}
private void handleTimestamp(long timestamp) {
- if (logger.logsDebug()) {
- logger.debug("handling timestamp");
- }
+ logger.debug("{} Handling timestamp", label);
long timestampDelta = timestamp - System.currentTimeMillis();
Map updates = new HashMap<>();
updates.put(Constants.DOT_INFO_SERVERTIME_OFFSET, timestampDelta);
@@ -930,9 +886,7 @@ assert canSendWrites()
new ConnectionRequestCallback() {
@Override
public void onResponse(Map response) {
- if (logger.logsDebug()) {
- logger.debug(action + " response: " + response);
- }
+ logger.debug("{} {} response: {}", label, action, response);
OutstandingPut currentPut = outstandingPuts.get(putId);
if (currentPut == put) {
@@ -948,10 +902,8 @@ public void onResponse(Map response) {
}
}
} else {
- if (logger.logsDebug()) {
- logger.debug(
- "Ignoring on complete for put " + putId + " because it was removed already.");
- }
+ logger.debug("{} Ignoring on complete for put {} because it was removed already.",
+ label, putId);
}
doIdleCheck();
}
@@ -1032,17 +984,13 @@ public void onResponse(Map response) {
String status = (String) response.get(REQUEST_STATUS);
if (!status.equals("ok")) {
String errorMessage = (String) response.get(SERVER_DATA_UPDATE_BODY);
- if (logger.logsDebug()) {
- logger.debug(
- "Failed to send stats: " + status + " (message: " + errorMessage + ")");
- }
+ logger.debug(
+ "{} Failed to send stats: {} (message: {})", label, stats, errorMessage);
}
}
});
} else {
- if (logger.logsDebug()) {
- logger.debug("Not sending stats because stats are empty");
- }
+ logger.debug("{} Not sending stats because stats are empty", label);
}
}
@@ -1051,11 +999,9 @@ private void warnOnListenerWarnings(List warnings, ListenQuerySpec query
if (warnings.contains("no_index")) {
String indexSpec = "\".indexOn\": \"" + query.queryParams.get("i") + '\"';
logger.warn(
- "Using an unspecified index. Consider adding '"
- + indexSpec
- + "' at "
- + ConnectionUtils.pathToString(query.path)
- + " to your security and Firebase Database rules for better performance");
+ "{} Using an unspecified index. Consider adding '{}' at {} to your security and "
+ + "Firebase Database rules for better performance",
+ label, indexSpec, ConnectionUtils.pathToString(query.path));
}
}
@@ -1064,9 +1010,7 @@ private void sendConnectStats() {
assert !this.context.isPersistenceEnabled()
: "Stats for persistence on JVM missing (persistence not yet supported)";
stats.put("sdk.admin_java." + context.getClientSdkVersion().replace('.', '-'), 1);
- if (logger.logsDebug()) {
- logger.debug("Sending first connection stats");
- }
+ logger.debug("{} Sending first connection stats", label);
sendStats(stats);
}
diff --git a/src/main/java/com/google/firebase/database/connection/WebsocketConnection.java b/src/main/java/com/google/firebase/database/connection/WebsocketConnection.java
index 9b28a19dd..3e29db07a 100644
--- a/src/main/java/com/google/firebase/database/connection/WebsocketConnection.java
+++ b/src/main/java/com/google/firebase/database/connection/WebsocketConnection.java
@@ -20,7 +20,6 @@
import static com.google.common.base.Preconditions.checkState;
import com.google.common.collect.ImmutableList;
-import com.google.firebase.database.logging.LogWrapper;
import com.google.firebase.database.util.JsonMapper;
import java.io.EOFException;
@@ -33,6 +32,8 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Represents a WebSocket connection to the Firebase Realtime Database. This abstraction acts as
@@ -47,11 +48,12 @@ class WebsocketConnection {
private static final long CONNECT_TIMEOUT_MS = 30 * 1000; // 30 seconds
private static final int MAX_FRAME_SIZE = 16384;
private static final AtomicLong CONN_ID = new AtomicLong(0);
+ private static final Logger logger = LoggerFactory.getLogger(WebsocketConnection.class);
private final ScheduledExecutorService executorService;
- private final LogWrapper logger;
private final WSClient conn;
private final Delegate delegate;
+ private final String label;
private StringList buffer;
private boolean everConnected = false;
@@ -75,8 +77,7 @@ class WebsocketConnection {
WSClientFactory clientFactory) {
this.executorService = connectionContext.getExecutorService();
this.delegate = delegate;
- this.logger = new LogWrapper(connectionContext.getLogger(), WebsocketConnection.class,
- "ws_" + CONN_ID.getAndIncrement());
+ this.label = "[ws_" + CONN_ID.getAndIncrement() + "]";
this.conn = clientFactory.newClient(new WSClientHandlerImpl());
}
@@ -99,9 +100,7 @@ void start() {
}
void close() {
- if (logger.logsDebug()) {
- logger.debug("websocket is being closed");
- }
+ logger.debug("{} Websocket is being closed", label);
isClosed = true;
conn.close();
@@ -130,7 +129,7 @@ void send(Map message) {
conn.send(seg);
}
} catch (IOException e) {
- logger.error("Failed to serialize message: " + message.toString(), e);
+ logger.error("{} Failed to serialize message: {}", label, message, e);
closeAndNotify();
}
}
@@ -150,9 +149,7 @@ private List splitIntoFrames(String src, int maxFrameSize) {
}
private void handleNewFrameCount(int numFrames) {
- if (logger.logsDebug()) {
- logger.debug("HandleNewFrameCount: " + numFrames);
- }
+ logger.debug("{} Handle new frame count: {}", label, numFrames);
buffer = new StringList(numFrames);
}
@@ -165,15 +162,13 @@ private void appendFrame(String message) {
String combined = buffer.combine();
try {
Map decoded = JsonMapper.parseJson(combined);
- if (logger.logsDebug()) {
- logger.debug("handleIncomingFrame complete frame: " + decoded);
- }
+ logger.debug("{} Parsed complete frame: {}", label, decoded);
delegate.onMessage(decoded);
} catch (IOException e) {
- logger.error("Error parsing frame: " + combined, e);
+ logger.error("{} Error parsing frame: {}", label, combined, e);
closeAndNotify();
} catch (ClassCastException e) {
- logger.error("Error parsing frame (cast error): " + combined, e);
+ logger.error("{} Error parsing frame (cast error): {}", label, combined, e);
closeAndNotify();
}
}
@@ -218,13 +213,10 @@ private void resetKeepAlive() {
}
if (keepAlive != null) {
keepAlive.cancel(false);
- if (logger.logsDebug()) {
- logger.debug("Reset keepAlive. Remaining: " + keepAlive.getDelay(TimeUnit.MILLISECONDS));
- }
+ logger.debug("{} Reset keepAlive. Remaining: {}", label,
+ keepAlive.getDelay(TimeUnit.MILLISECONDS));
} else {
- if (logger.logsDebug()) {
- logger.debug("Reset keepAlive");
- }
+ logger.debug("{} Reset keepAlive", label);
}
keepAlive = executorService.schedule(nop(), KEEP_ALIVE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
}
@@ -253,18 +245,14 @@ private void closeAndNotify() {
private void onClosed() {
if (!isClosed) {
- if (logger.logsDebug()) {
- logger.debug("closing itself");
- }
+ logger.debug("{} Closing itself", label);
closeAndNotify();
}
}
private void closeIfNeverConnected() {
if (!everConnected && !isClosed) {
- if (logger.logsDebug()) {
- logger.debug("timed out on connect");
- }
+ logger.debug("{} Timed out on connect", label);
closeAndNotify();
}
}
@@ -278,9 +266,7 @@ private class WSClientHandlerImpl implements WSClientEventHandler {
@Override
public void onOpen() {
- if (logger.logsDebug()) {
- logger.debug("websocket opened");
- }
+ logger.debug("{} Websocket opened", label);
executorService.execute(new Runnable() {
@Override
public void run() {
@@ -293,9 +279,7 @@ public void run() {
@Override
public void onMessage(final String message) {
- if (logger.logsDebug()) {
- logger.debug("ws message: " + message);
- }
+ logger.debug("{} WS message: {}", label, message);
executorService.execute(new Runnable() {
@Override
public void run() {
@@ -306,9 +290,7 @@ public void run() {
@Override
public void onClose() {
- if (logger.logsDebug()) {
- logger.debug("closed");
- }
+ logger.debug("{} Closed", label);
if (!isClosed) {
// If the connection tear down was initiated by the higher-layer, isClosed will already
// be true. Nothing more to do in that case.
@@ -325,9 +307,9 @@ public void run() {
@Override
public void onError(final Throwable e) {
if (e instanceof EOFException || e.getCause() instanceof EOFException) {
- logger.debug("WebSocket reached EOF", e);
+ logger.debug("{} WebSocket reached EOF", label, e);
} else {
- logger.error("WebSocket error", e);
+ logger.error("{} WebSocket error", label, e);
}
executorService.execute(
new Runnable() {
diff --git a/src/main/java/com/google/firebase/database/connection/util/RetryHelper.java b/src/main/java/com/google/firebase/database/connection/util/RetryHelper.java
index 2563a30ca..f8f6bb77a 100644
--- a/src/main/java/com/google/firebase/database/connection/util/RetryHelper.java
+++ b/src/main/java/com/google/firebase/database/connection/util/RetryHelper.java
@@ -16,18 +16,18 @@
package com.google.firebase.database.connection.util;
-import com.google.firebase.database.logging.LogWrapper;
-import com.google.firebase.database.logging.Logger;
-
import java.util.Random;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class RetryHelper {
+ private static final Logger logger = LoggerFactory.getLogger(RetryHelper.class);
+
private final ScheduledExecutorService executorService;
- private final LogWrapper logger;
/** The minimum delay for a retry in ms. */
private final long minRetryDelayAfterFailure;
/** The maximum retry delay in ms. */
@@ -49,13 +49,11 @@ public class RetryHelper {
private RetryHelper(
ScheduledExecutorService executorService,
- LogWrapper logger,
long minRetryDelayAfterFailure,
long maxRetryDelay,
double retryExponent,
double jitterFactor) {
this.executorService = executorService;
- this.logger = logger;
this.minRetryDelayAfterFailure = minRetryDelayAfterFailure;
this.maxRetryDelay = maxRetryDelay;
this.retryExponent = retryExponent;
@@ -84,7 +82,7 @@ public void retry(final Runnable runnable) {
+ (jitterFactor * currentRetryDelay * random.nextDouble()));
}
this.lastWasSuccess = false;
- logger.debug("Scheduling retry in %dms", delay);
+ logger.debug("Scheduling retry in {}ms", delay);
Runnable wrapped =
new Runnable() {
@Override
@@ -119,15 +117,13 @@ public void cancel() {
public static class Builder {
private final ScheduledExecutorService service;
- private final LogWrapper logger;
private long minRetryDelayAfterFailure = 1000;
private double jitterFactor = 0.5;
private long retryMaxDelay = 30 * 1000;
private double retryExponent = 1.3;
- public Builder(ScheduledExecutorService service, Logger logger, Class tag) {
+ public Builder(ScheduledExecutorService service, Class tag) {
this.service = service;
- this.logger = new LogWrapper(logger, tag);
}
public Builder withMinDelayAfterFailure(long delay) {
@@ -156,7 +152,6 @@ public Builder withJitterFactor(double random) {
public RetryHelper build() {
return new RetryHelper(
this.service,
- this.logger,
this.minRetryDelayAfterFailure,
this.retryMaxDelay,
this.retryExponent,
diff --git a/src/main/java/com/google/firebase/database/core/Context.java b/src/main/java/com/google/firebase/database/core/Context.java
index 52c07b8c6..da68861cc 100644
--- a/src/main/java/com/google/firebase/database/core/Context.java
+++ b/src/main/java/com/google/firebase/database/core/Context.java
@@ -26,29 +26,24 @@
import com.google.firebase.database.connection.PersistentConnection;
import com.google.firebase.database.core.persistence.NoopPersistenceManager;
import com.google.firebase.database.core.persistence.PersistenceManager;
-import com.google.firebase.database.logging.LogWrapper;
-import com.google.firebase.database.logging.Logger;
import com.google.firebase.database.utilities.DefaultRunLoop;
-import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
public class Context {
private static final long DEFAULT_CACHE_SIZE = 10 * 1024 * 1024;
- protected Logger logger;
- protected EventTarget eventTarget;
- protected AuthTokenProvider authTokenProvider;
- protected RunLoop runLoop;
- protected String persistenceKey;
- protected List loggedComponents;
- protected String userAgent;
- protected Logger.Level logLevel = Logger.Level.INFO;
- protected boolean persistenceEnabled;
- protected long cacheSize = DEFAULT_CACHE_SIZE;
- protected FirebaseApp firebaseApp;
- private PersistenceManager forcedPersistenceManager;
+ FirebaseApp firebaseApp;
+
+ EventTarget eventTarget;
+ AuthTokenProvider authTokenProvider;
+ RunLoop runLoop;
+ String persistenceKey;
+ boolean persistenceEnabled;
+ long cacheSize = DEFAULT_CACHE_SIZE;
+
+ private String userAgent;
private boolean frozen = false;
private boolean stopped = false;
@@ -78,19 +73,11 @@ public void onError(String error) {
private Platform getPlatform() {
if (platform == null) {
- if (GaePlatform.isActive()) {
- platform = new GaePlatform(firebaseApp);
- } else {
- platform = new JvmPlatform(firebaseApp);
- }
+ platform = new JvmPlatform(firebaseApp);
}
return platform;
}
- public boolean isFrozen() {
- return frozen;
- }
-
public boolean isStopped() {
return stopped;
}
@@ -110,8 +97,6 @@ public void requireStarted() {
}
private void initServices() {
- // Do the logger first, so that other components can get a LogWrapper
- ensureLogger();
// Cache platform
getPlatform();
ensureUserAgent();
@@ -137,28 +122,15 @@ void stop() {
}
}
- protected void assertUnfrozen() {
- if (isFrozen()) {
+ void assertUnfrozen() {
+ if (frozen) {
throw new DatabaseException(
"Modifications to DatabaseConfig objects must occur before they are in use");
}
}
- public LogWrapper getLogger(String component) {
- return new LogWrapper(logger, component, null);
- }
-
- public LogWrapper getLogger(Class component) {
- return new LogWrapper(logger, component);
- }
-
- public LogWrapper getLogger(Class component, String prefix) {
- return new LogWrapper(logger, component, prefix);
- }
-
public ConnectionContext getConnectionContext() {
return new ConnectionContext(
- this.logger,
wrapAuthTokenProvider(this.getAuthTokenProvider()),
this.getExecutorService(),
this.isPersistenceEnabled(),
@@ -168,10 +140,6 @@ public ConnectionContext getConnectionContext() {
}
PersistenceManager getPersistenceManager(String firebaseId) {
- // TODO[persistence]: Create this once and store it.
- if (forcedPersistenceManager != null) {
- return forcedPersistenceManager;
- }
if (this.persistenceEnabled) {
PersistenceManager cache = platform.createPersistenceManager(this, firebaseId);
if (cache == null) {
@@ -193,11 +161,6 @@ public long getPersistenceCacheSizeBytes() {
return this.cacheSize;
}
- // For testing
- void forcePersistenceManager(PersistenceManager persistenceManager) {
- this.forcedPersistenceManager = persistenceManager;
- }
-
public EventTarget getEventTarget() {
return eventTarget;
}
@@ -210,14 +173,6 @@ public String getUserAgent() {
return userAgent;
}
- public String getPlatformVersion() {
- return getPlatform().getPlatformVersion();
- }
-
- public String getSessionPersistenceKey() {
- return this.persistenceKey;
- }
-
public AuthTokenProvider getAuthTokenProvider() {
return this.authTokenProvider;
}
@@ -237,12 +192,6 @@ private ScheduledExecutorService getExecutorService() {
return ((DefaultRunLoop) loop).getExecutorService();
}
- private void ensureLogger() {
- if (logger == null) {
- logger = getPlatform().newLogger(this, logLevel, loggedComponents);
- }
- }
-
private void ensureRunLoop() {
if (runLoop == null) {
runLoop = platform.newRunLoop(this);
diff --git a/src/main/java/com/google/firebase/database/core/DatabaseConfig.java b/src/main/java/com/google/firebase/database/core/DatabaseConfig.java
index 491098d6a..844f59266 100644
--- a/src/main/java/com/google/firebase/database/core/DatabaseConfig.java
+++ b/src/main/java/com/google/firebase/database/core/DatabaseConfig.java
@@ -18,9 +18,6 @@
import com.google.firebase.FirebaseApp;
import com.google.firebase.database.DatabaseException;
-import com.google.firebase.database.Logger;
-
-import java.util.List;
/**
* TODO: Since this is no longer public, we should merge it with Context and clean all
@@ -29,21 +26,6 @@
*/
public class DatabaseConfig extends Context {
- // TODO: Remove this from the public API since we currently can't pass logging
- // across AIDL interface.
-
- /**
- * If you would like to provide a custom log target, pass an object that implements the {@link
- * com.google.firebase.database.Logger Logger} interface.
- *
- * @hide
- * @param logger The custom logger that will be called with all log messages
- */
- public synchronized void setLogger(com.google.firebase.database.logging.Logger logger) {
- assertUnfrozen();
- this.logger = logger;
- }
-
/**
* In the default setup, the Firebase Database library will create a thread to handle all
* callbacks. On Android, it will attempt to use the main debugComponents) {
- assertUnfrozen();
- setLogLevel(Logger.Level.DEBUG);
- loggedComponents = debugComponents;
- }
-
public void setRunLoop(RunLoop runLoop) {
this.runLoop = runLoop;
}
diff --git a/src/main/java/com/google/firebase/database/core/GaePlatform.java b/src/main/java/com/google/firebase/database/core/GaePlatform.java
deleted file mode 100644
index b7698f3de..000000000
--- a/src/main/java/com/google/firebase/database/core/GaePlatform.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.firebase.database.core;
-
-import com.google.firebase.FirebaseApp;
-import com.google.firebase.ImplFirebaseTrampolines;
-import com.google.firebase.database.FirebaseDatabase;
-import com.google.firebase.database.connection.ConnectionContext;
-import com.google.firebase.database.connection.HostInfo;
-import com.google.firebase.database.connection.PersistentConnection;
-import com.google.firebase.database.connection.PersistentConnectionImpl;
-import com.google.firebase.database.core.persistence.PersistenceManager;
-import com.google.firebase.database.logging.DefaultLogger;
-import com.google.firebase.database.logging.LogWrapper;
-import com.google.firebase.database.logging.Logger;
-import com.google.firebase.database.utilities.DefaultRunLoop;
-import com.google.firebase.internal.GaeThreadFactory;
-import com.google.firebase.internal.RevivingScheduledExecutor;
-
-import java.util.List;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-
-/**
- * Represents a Google AppEngine platform.
- *
- * This class is not thread-safe.
- */
-class GaePlatform implements Platform {
-
- private static final String PROCESS_PLATFORM = "AppEngine";
- private final FirebaseApp firebaseApp;
-
- public GaePlatform(FirebaseApp firebaseApp) {
- this.firebaseApp = firebaseApp;
- }
-
- public static boolean isActive() {
- return GaeThreadFactory.isAvailable();
- }
-
- @Override
- public Logger newLogger(Context ctx, Logger.Level level, List components) {
- return new DefaultLogger(level, components);
- }
-
- private ThreadFactory getGaeThreadFactory() {
- return ImplFirebaseTrampolines.getThreadFactory(firebaseApp);
- }
-
- @Override
- public EventTarget newEventTarget(Context ctx) {
- RevivingScheduledExecutor eventExecutor =
- new RevivingScheduledExecutor(getGaeThreadFactory(), "FirebaseDatabaseEventTarget", true);
- return new ThreadPoolEventTarget(eventExecutor);
- }
-
- @Override
- public RunLoop newRunLoop(final Context context) {
- final LogWrapper logger = context.getLogger(RunLoop.class);
- return new DefaultRunLoop(getGaeThreadFactory(), /* periodicRestart= */ true, context) {
- @Override
- public void handleException(Throwable e) {
- logger.error(DefaultRunLoop.messageForException(e), e);
- }
- };
- }
-
- @Override
- public AuthTokenProvider newAuthTokenProvider(ScheduledExecutorService executorService) {
- return new JvmAuthTokenProvider(this.firebaseApp, executorService);
- }
-
- @Override
- public PersistentConnection newPersistentConnection(
- Context context,
- ConnectionContext connectionContext,
- HostInfo info,
- PersistentConnection.Delegate delegate) {
- return new PersistentConnectionImpl(context.getConnectionContext(), info, delegate);
- }
-
- @Override
- public String getUserAgent(Context ctx) {
- return PROCESS_PLATFORM + "/" + DEVICE;
- }
-
- @Override
- public String getPlatformVersion() {
- return "gae-" + FirebaseDatabase.getSdkVersion();
- }
-
- @Override
- public PersistenceManager createPersistenceManager(Context ctx, String namespace) {
- return null;
- }
-
- @Override
- public ThreadInitializer getThreadInitializer() {
- return new ThreadInitializer() {
- @Override
- public void setName(Thread t, String name) {
- // Unsupported by GAE
- }
-
- @Override
- public void setDaemon(Thread t, boolean isDaemon) {
- // Unsupported by GAE
- }
-
- @Override
- public void setUncaughtExceptionHandler(Thread t, Thread.UncaughtExceptionHandler handler) {
- // Unsupported by GAE
- }
- };
- }
-}
diff --git a/src/main/java/com/google/firebase/database/core/JvmPlatform.java b/src/main/java/com/google/firebase/database/core/JvmPlatform.java
index 30a2e25df..2a226c078 100644
--- a/src/main/java/com/google/firebase/database/core/JvmPlatform.java
+++ b/src/main/java/com/google/firebase/database/core/JvmPlatform.java
@@ -24,14 +24,12 @@
import com.google.firebase.database.connection.PersistentConnection;
import com.google.firebase.database.connection.PersistentConnectionImpl;
import com.google.firebase.database.core.persistence.PersistenceManager;
-import com.google.firebase.database.logging.DefaultLogger;
-import com.google.firebase.database.logging.LogWrapper;
-import com.google.firebase.database.logging.Logger;
import com.google.firebase.database.utilities.DefaultRunLoop;
-import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
class JvmPlatform implements Platform {
@@ -39,24 +37,19 @@ class JvmPlatform implements Platform {
private final FirebaseApp firebaseApp;
- public JvmPlatform(FirebaseApp firebaseApp) {
+ JvmPlatform(FirebaseApp firebaseApp) {
this.firebaseApp = firebaseApp;
}
- @Override
- public Logger newLogger(Context ctx, Logger.Level level, List components) {
- return new DefaultLogger(level, components);
- }
-
@Override
public EventTarget newEventTarget(Context ctx) {
ThreadFactory threadFactory = ImplFirebaseTrampolines.getThreadFactory(firebaseApp);
- return new ThreadPoolEventTarget(threadFactory, ThreadInitializer.defaultInstance);
+ return new ThreadPoolEventTarget(threadFactory);
}
@Override
public RunLoop newRunLoop(final Context context) {
- final LogWrapper logger = context.getLogger(RunLoop.class);
+ final Logger logger = LoggerFactory.getLogger(RunLoop.class);
ThreadFactory threadFactory = ImplFirebaseTrampolines.getThreadFactory(firebaseApp);
return new DefaultRunLoop(threadFactory) {
@Override
@@ -94,9 +87,4 @@ public String getPlatformVersion() {
public PersistenceManager createPersistenceManager(Context ctx, String namespace) {
return null;
}
-
- @Override
- public ThreadInitializer getThreadInitializer() {
- return ThreadInitializer.defaultInstance;
- }
}
diff --git a/src/main/java/com/google/firebase/database/core/Platform.java b/src/main/java/com/google/firebase/database/core/Platform.java
index 5e701c408..2d2742a62 100644
--- a/src/main/java/com/google/firebase/database/core/Platform.java
+++ b/src/main/java/com/google/firebase/database/core/Platform.java
@@ -20,17 +20,13 @@
import com.google.firebase.database.connection.HostInfo;
import com.google.firebase.database.connection.PersistentConnection;
import com.google.firebase.database.core.persistence.PersistenceManager;
-import com.google.firebase.database.logging.Logger;
-import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
public interface Platform {
String DEVICE = "AdminJava";
- Logger newLogger(Context ctx, Logger.Level level, List components);
-
EventTarget newEventTarget(Context ctx);
RunLoop newRunLoop(Context ctx);
@@ -48,6 +44,4 @@ PersistentConnection newPersistentConnection(
String getPlatformVersion();
PersistenceManager createPersistenceManager(Context ctx, String firebaseId);
-
- ThreadInitializer getThreadInitializer();
}
diff --git a/src/main/java/com/google/firebase/database/core/Repo.java b/src/main/java/com/google/firebase/database/core/Repo.java
index add6ff3e0..98777d04d 100644
--- a/src/main/java/com/google/firebase/database/core/Repo.java
+++ b/src/main/java/com/google/firebase/database/core/Repo.java
@@ -38,7 +38,6 @@
import com.google.firebase.database.core.view.Event;
import com.google.firebase.database.core.view.EventRaiser;
import com.google.firebase.database.core.view.QuerySpec;
-import com.google.firebase.database.logging.LogWrapper;
import com.google.firebase.database.snapshot.ChildKey;
import com.google.firebase.database.snapshot.EmptyNode;
import com.google.firebase.database.snapshot.IndexedNode;
@@ -54,6 +53,8 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class Repo implements PersistentConnection.Delegate {
@@ -67,14 +68,14 @@ public class Repo implements PersistentConnection.Delegate {
private static final String TRANSACTION_TOO_MANY_RETRIES = "maxretries";
private static final String TRANSACTION_OVERRIDE_BY_SET = "overriddenBySet";
+
+ private static final Logger logger = LoggerFactory.getLogger(Repo.class);
+
private final RepoInfo repoInfo;
private final OffsetClock serverClock = new OffsetClock(new DefaultClock(), 0);
private final PersistentConnection connection;
private final EventRaiser eventRaiser;
private final Context ctx;
- private final LogWrapper operationLogger;
- private final LogWrapper transactionLogger;
- private final LogWrapper dataLogger;
private SnapshotHolder infoData;
private SparseSnapshotTree onDisconnect;
private Tree> transactionQueueTree;
@@ -90,11 +91,6 @@ public class Repo implements PersistentConnection.Delegate {
this.repoInfo = repoInfo;
this.ctx = ctx;
this.database = database;
-
- operationLogger = this.ctx.getLogger(Repo.class);
- transactionLogger = this.ctx.getLogger(Repo.class.getName() + ".Transaction");
- dataLogger = this.ctx.getLogger(Repo.class.getName() + ".DataOperation");
-
this.eventRaiser = new EventRaiser(this.ctx);
HostInfo hostInfo = new HostInfo(repoInfo.host, repoInfo.namespace, repoInfo.secure);
@@ -134,7 +130,7 @@ private void deferredInitialization() {
new AuthTokenProvider.TokenChangeListener() {
@Override
public void onTokenChange(String token) {
- operationLogger.debug("Auth token changed, triggering auth token refresh");
+ logger.debug("Auth token changed, triggering auth token refresh");
connection.refreshAuthToken(token);
}
});
@@ -150,7 +146,7 @@ public void onTokenChange(String token) {
transactionQueueTree = new Tree<>();
- infoSyncTree = new SyncTree(ctx, new NoopPersistenceManager(),
+ infoSyncTree = new SyncTree(new NoopPersistenceManager(),
new SyncTree.ListenProvider() {
@Override
public void startListening(
@@ -178,7 +174,7 @@ public void run() {
public void stopListening(QuerySpec query, Tag tag) {}
});
- serverSyncTree = new SyncTree(ctx, persistenceManager,
+ serverSyncTree = new SyncTree(persistenceManager,
new SyncTree.ListenProvider() {
@Override
public void startListening(
@@ -263,12 +259,8 @@ boolean hasListeners() {
public void onDataUpdate(
List pathSegments, Object message, boolean isMerge, Long optTag) {
Path path = new Path(pathSegments);
- if (operationLogger.logsDebug()) {
- operationLogger.debug("onDataUpdate: " + path);
- }
- if (dataLogger.logsDebug()) {
- operationLogger.debug("onDataUpdate: " + path + " " + message);
- }
+ logger.debug("onDataUpdate: {} {}", path, message);
+
List extends Event> events;
try {
@@ -306,7 +298,7 @@ public void onDataUpdate(
postEvents(events);
} catch (DatabaseException e) {
- operationLogger.error("FIREBASE INTERNAL ERROR", e);
+ logger.error("Firebase internal error", e);
}
}
@@ -316,12 +308,7 @@ public void onRangeMergeUpdate(
List merges,
Long tagNumber) {
Path path = new Path(pathSegments);
- if (operationLogger.logsDebug()) {
- operationLogger.debug("onRangeMergeUpdate: " + path);
- }
- if (dataLogger.logsDebug()) {
- operationLogger.debug("onRangeMergeUpdate: " + path + " " + merges);
- }
+ logger.debug("onRangeMergeUpdate: {} {}", path, merges);
List parsedMerges = new ArrayList<>(merges.size());
for (com.google.firebase.database.connection.RangeMerge merge : merges) {
@@ -383,12 +370,7 @@ public void setValue(
final Path path,
Node newValueUnresolved,
final DatabaseReference.CompletionListener onComplete) {
- if (operationLogger.logsDebug()) {
- operationLogger.debug("set: " + path);
- }
- if (dataLogger.logsDebug()) {
- dataLogger.debug("set: " + path + " " + newValueUnresolved);
- }
+ logger.debug("set: {} {}", path, newValueUnresolved);
Map serverValues = ServerValues.generateServerValues(serverClock);
Node newValue = ServerValues.resolveDeferredValueSnapshot(newValueUnresolved, serverValues);
@@ -421,16 +403,9 @@ public void updateChildren(
CompoundWrite updates,
final DatabaseReference.CompletionListener onComplete,
Map unParsedUpdates) {
- if (operationLogger.logsDebug()) {
- operationLogger.debug("update: " + path);
- }
- if (dataLogger.logsDebug()) {
- dataLogger.debug("update: " + path + " " + unParsedUpdates);
- }
+ logger.debug("update: {} {}", path, unParsedUpdates);
if (updates.isEmpty()) {
- if (operationLogger.logsDebug()) {
- operationLogger.debug("update called with no changes. No-op");
- }
+ logger.debug("update called with no changes. No-op");
// dispatch on complete
callOnComplete(onComplete, null, path);
return;
@@ -468,9 +443,7 @@ public void onRequestResult(String optErrorCode, String optErrorMessage) {
}
public void purgeOutstandingWrites() {
- if (operationLogger.logsDebug()) {
- operationLogger.debug("Purging writes");
- }
+ logger.debug("Purging writes");
List extends Event> events = serverSyncTree.removeAllWrites();
postEvents(events);
// Abort any transactions
@@ -619,7 +592,7 @@ private void updateInfo(ChildKey childKey, Object value) {
List extends Event> events = this.infoSyncTree.applyServerOverwrite(path, node);
this.postEvents(events);
} catch (DatabaseException e) {
- operationLogger.error("Failed to parse info update", e);
+ logger.error("Failed to parse info update", e);
}
}
@@ -652,21 +625,16 @@ private void warnIfWriteFailed(String writeType, Path path, DatabaseError error)
if (error != null
&& !(error.getCode() == DatabaseError.DATA_STALE
|| error.getCode() == DatabaseError.WRITE_CANCELED)) {
- operationLogger.warn(writeType + " at " + path.toString() + " failed: " + error.toString());
+ logger.warn(writeType + " at " + path.toString() + " failed: " + error.toString());
}
}
public void startTransaction(Path path, final Transaction.Handler handler, boolean applyLocally) {
- if (operationLogger.logsDebug()) {
- operationLogger.debug("transaction: " + path);
- }
- if (dataLogger.logsDebug()) {
- operationLogger.debug("transaction: " + path);
- }
+ logger.debug("transaction: {}", path);
if (this.ctx.isPersistenceEnabled() && !loggedTransactionPersistenceWarning) {
loggedTransactionPersistenceWarning = true;
- transactionLogger.info(
+ logger.info(
"runTransaction() usage detected while persistence is enabled. Please be aware that "
+ "transactions *will not* be persisted across database restarts. See "
+ "https://www.firebase.com/docs/android/guide/offline-capabilities.html"
@@ -1142,11 +1110,7 @@ public void visitTree(Tree> tree) {
private Path abortTransactions(Path path, final int reason) {
Path affectedPath = getAncestorTransactionNode(path).getPath();
-
- if (transactionLogger.logsDebug()) {
- operationLogger.debug(
- "Aborting transactions for path: " + path + ". Affected: " + affectedPath);
- }
+ logger.debug("Aborting transactions for path: {}. Affected: {}", path, affectedPath);
Tree> transactionNode = transactionQueueTree.subTree(path);
transactionNode.forEachAncestor(
@@ -1247,7 +1211,7 @@ private void runTransactionOnComplete(Transaction.Handler handler, DatabaseError
try {
handler.onComplete(error, committed, snapshot);
} catch (Exception e) {
- operationLogger.error("Exception in transaction onComplete callback", e);
+ logger.error("Exception in transaction onComplete callback", e);
}
}
diff --git a/src/main/java/com/google/firebase/database/core/SyncTree.java b/src/main/java/com/google/firebase/database/core/SyncTree.java
index 17fcad445..f7da11750 100644
--- a/src/main/java/com/google/firebase/database/core/SyncTree.java
+++ b/src/main/java/com/google/firebase/database/core/SyncTree.java
@@ -37,7 +37,6 @@
import com.google.firebase.database.core.view.Event;
import com.google.firebase.database.core.view.QuerySpec;
import com.google.firebase.database.core.view.View;
-import com.google.firebase.database.logging.LogWrapper;
import com.google.firebase.database.snapshot.ChildKey;
import com.google.firebase.database.snapshot.CompoundHash;
import com.google.firebase.database.snapshot.EmptyNode;
@@ -57,6 +56,8 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* SyncTree is the central class for managing event callback registration, data caching, views
@@ -80,6 +81,9 @@ public class SyncTree {
// Size after which we start including the compound hash
private static final long SIZE_THRESHOLD_FOR_COMPOUND_HASH = 1024;
+
+ private static final Logger logger = LoggerFactory.getLogger(SyncTree.class);
+
/**
* A tree of all pending user writes (user-initiated set()'s, transaction()'s, update()'s, etc.).
*/
@@ -90,14 +94,13 @@ public class SyncTree {
private final Set keepSyncedQueries;
private final ListenProvider listenProvider;
private final PersistenceManager persistenceManager;
- private final LogWrapper logger;
/** Tree of SyncPoints. There's a SyncPoint at any location that has 1 or more views. */
private ImmutableTree