Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Unreleased

- [added] `FirebaseAuth`, `FirebaseMessaging` and `FirebaseInstanceId`
interfaces now expose a set of blocking methods. Each operation has
blocking an asynchronous versions.
- [changed] Removed the deprecated `FirebaseCredential` interface.
- [changed] Removed the deprecated `Task` interface along with the
`com.google.firebase.tasks` package.
- [changed] Dropped support for App Engine's Java 7 runtime. Developers
are advised to use the Admin SDK with Java 8 when deploying to App
Engine.
- [changed] Removed the deprecated `FirebaseDatabase.setLogLevel()` API
and the related logging utilities. Developers should use SLF4J to
configure logging directly.

# v5.11.0

Expand Down
98 changes: 41 additions & 57 deletions src/main/java/com/google/firebase/FirebaseApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.api.client.googleapis.util.Utils;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonParser;
import com.google.api.core.ApiFuture;
import com.google.auth.oauth2.AccessToken;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.OAuth2Credentials;
Expand All @@ -34,18 +34,13 @@
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.io.BaseEncoding;
import com.google.firebase.internal.FirebaseAppStore;
import com.google.firebase.internal.FirebaseScheduledExecutor;
import com.google.firebase.internal.FirebaseService;
import com.google.firebase.internal.GaeThreadFactory;
import com.google.firebase.internal.ListenableFuture2ApiFuture;
import com.google.firebase.internal.NonNull;
import com.google.firebase.internal.Nullable;

import com.google.firebase.internal.RevivingScheduledExecutor;
import com.google.firebase.tasks.Task;
import com.google.firebase.tasks.Tasks;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
Expand Down Expand Up @@ -176,6 +171,9 @@ public static FirebaseApp getInstance(@NonNull String name) {
* by looking up the {@code FIREBASE_CONFIG} environment variable. If the value of
* the variable starts with <code>'{'</code>, it is parsed as a JSON object. Otherwise it is
* treated as a file name and the JSON content is read from the corresponding file.
*
* @throws IllegalStateException if the default app has already been initialized.
* @throws IllegalArgumentException if an error occurs while loading options from the environment.
*/
public static FirebaseApp initializeApp() {
return initializeApp(DEFAULT_APP_NAME);
Expand All @@ -185,13 +183,23 @@ public static FirebaseApp initializeApp() {
* Initializes a named {@link FirebaseApp} instance using Google Application Default Credentials.
* Loads additional {@link FirebaseOptions} from the environment in the same way as the
* {@link #initializeApp()} method.
*
* @throws IllegalStateException if an app with the same name has already been initialized.
* @throws IllegalArgumentException if an error occurs while loading options from the environment.
*/
public static FirebaseApp initializeApp(String name) {
return initializeApp(getOptionsFromEnvironment(), name);
try {
return initializeApp(getOptionsFromEnvironment(), name);
} catch (IOException e) {
throw new IllegalArgumentException(
Copy link
Contributor

@avishalom avishalom Mar 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change javadocs to IllegalArgumentException.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@avishalom avishalom Mar 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nm

"Failed to load settings from the system's environment variables", e);
}
}

/**
* Initializes the default {@link FirebaseApp} instance using the given options.
*
* @throws IllegalStateException if the default app has already been initialized.
*/
public static FirebaseApp initializeApp(FirebaseOptions options) {
return initializeApp(options, DEFAULT_APP_NAME);
Expand Down Expand Up @@ -241,19 +249,6 @@ static void clearInstancesForTest() {
}
}

/**
* Returns persistence key. Exists to support getting {@link FirebaseApp} persistence key after
* the app has been deleted.
*/
static String getPersistenceKey(String name, FirebaseOptions options) {
return BaseEncoding.base64Url().omitPadding().encode(name.getBytes(UTF_8));
}

/** Use this key to store data per FirebaseApp. */
String getPersistenceKey() {
return FirebaseApp.getPersistenceKey(getName(), getOptions());
}

private static List<String> getAllAppNames() {
Set<String> allAppNames = new HashSet<>();
synchronized (appsLock) {
Expand Down Expand Up @@ -317,10 +312,7 @@ String getProjectId() {

@Override
public boolean equals(Object o) {
if (!(o instanceof FirebaseApp)) {
return false;
}
return name.equals(((FirebaseApp) o).getName());
return o instanceof FirebaseApp && name.equals(((FirebaseApp) o).getName());
}

@Override
Expand Down Expand Up @@ -383,8 +375,8 @@ private ScheduledExecutorService ensureScheduledExecutorService() {
synchronized (lock) {
checkNotDeleted();
if (scheduledExecutor == null) {
scheduledExecutor = new RevivingScheduledExecutor(threadManager.getThreadFactory(),
"firebase-scheduled-worker", GaeThreadFactory.isAvailable());
scheduledExecutor = new FirebaseScheduledExecutor(getThreadFactory(),
"firebase-scheduled-worker");
}
}
}
Expand All @@ -395,10 +387,9 @@ ThreadFactory getThreadFactory() {
return threadManager.getThreadFactory();
}

// TODO: Return an ApiFuture once Task API is fully removed.
<T> Task<T> submit(Callable<T> command) {
<T> ApiFuture<T> submit(Callable<T> command) {
checkNotNull(command);
return Tasks.call(executors.getListeningExecutor(), command);
return new ListenableFuture2ApiFuture<>(executors.getListeningExecutor().submit(command));
}

<T> ScheduledFuture<T> schedule(Callable<T> command, long delayMillis) {
Expand Down Expand Up @@ -462,7 +453,7 @@ static class TokenRefresher implements CredentialsChangedListener {
}

@Override
public final synchronized void onChanged(OAuth2Credentials credentials) throws IOException {
public final synchronized void onChanged(OAuth2Credentials credentials) {
if (state.get() != State.STARTED) {
return;
}
Expand Down Expand Up @@ -569,33 +560,26 @@ enum State {
}
}

private static FirebaseOptions getOptionsFromEnvironment() {
private static FirebaseOptions getOptionsFromEnvironment() throws IOException {
String defaultConfig = System.getenv(FIREBASE_CONFIG_ENV_VAR);
try {
if (Strings.isNullOrEmpty(defaultConfig)) {
return new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.build();
}
JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
FirebaseOptions.Builder builder = new FirebaseOptions.Builder();
JsonParser parser;
if (defaultConfig.startsWith("{")) {
parser = jsonFactory.createJsonParser(defaultConfig);
} else {
FileReader reader;
reader = new FileReader(defaultConfig);
parser = jsonFactory.createJsonParser(reader);
}
parser.parseAndClose(builder);
builder.setCredentials(GoogleCredentials.getApplicationDefault());

return builder.build();
if (Strings.isNullOrEmpty(defaultConfig)) {
return new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.getApplicationDefault())
.build();
}

} catch (FileNotFoundException e) {
throw new IllegalStateException(e);
} catch (IOException e) {
throw new IllegalStateException(e);
JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
FirebaseOptions.Builder builder = new FirebaseOptions.Builder();
JsonParser parser;
if (defaultConfig.startsWith("{")) {
parser = jsonFactory.createJsonParser(defaultConfig);
} else {
FileReader reader;
reader = new FileReader(defaultConfig);
parser = jsonFactory.createJsonParser(reader);
}
parser.parseAndClose(builder);
builder.setCredentials(GoogleCredentials.getApplicationDefault());
return builder.build();
}
}
44 changes: 20 additions & 24 deletions src/main/java/com/google/firebase/FirebaseOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,35 @@
import com.google.api.client.util.Key;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.base.Strings;
import com.google.firebase.auth.FirebaseCredential;
import com.google.firebase.auth.FirebaseCredentials;
import com.google.firebase.auth.internal.BaseCredential;
import com.google.firebase.auth.internal.FirebaseCredentialsAdapter;
import com.google.common.collect.ImmutableList;
import com.google.firebase.internal.FirebaseThreadManagers;
import com.google.firebase.internal.NonNull;
import com.google.firebase.internal.Nullable;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** Configurable Firebase options. */
public final class FirebaseOptions {

// TODO: deprecate and remove it once we can fetch these from Remote Config.
private static final List<String> 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 String databaseUrl;
private final String storageBucket;
Expand All @@ -55,7 +69,7 @@ public final class FirebaseOptions {
private FirebaseOptions(@NonNull FirebaseOptions.Builder builder) {
this.credentials = checkNotNull(builder.credentials,
"FirebaseOptions must be initialized with setCredentials().")
.createScoped(BaseCredential.FIREBASE_SCOPES);
.createScoped(FIREBASE_SCOPES);
this.databaseUrl = builder.databaseUrl;
this.databaseAuthVariableOverride = builder.databaseAuthVariableOverride;
this.projectId = builder.projectId;
Expand Down Expand Up @@ -260,24 +274,6 @@ public Builder setCredentials(GoogleCredentials credentials) {
return this;
}

/**
* Sets the <code>FirebaseCredential</code> to use to authenticate the SDK.
*
* @param credential A <code>FirebaseCredential</code> used to authenticate the SDK. See {@link
* FirebaseCredentials} for default implementations.
* @return This <code>Builder</code> instance is returned so subsequent calls can be chained.
* @deprecated Use {@link FirebaseOptions.Builder#setCredentials(GoogleCredentials)}.
*/
public Builder setCredential(@NonNull FirebaseCredential credential) {
checkNotNull(credential);
if (credential instanceof BaseCredential) {
this.credentials = ((BaseCredential) credential).getGoogleCredentials();
} else {
this.credentials = new FirebaseCredentialsAdapter(credential);
}
return this;
}

/**
* Sets the <code>auth</code> variable to be used by the Realtime Database rules.
*
Expand Down
13 changes: 3 additions & 10 deletions src/main/java/com/google/firebase/ImplFirebaseTrampolines.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

package com.google.firebase;

import com.google.api.core.ApiFuture;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.internal.FirebaseService;
import com.google.firebase.internal.NonNull;

import com.google.firebase.tasks.Task;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadFactory;

Expand All @@ -47,14 +47,6 @@ public static boolean isDefaultApp(@NonNull FirebaseApp app) {
return app.isDefaultApp();
}

public static String getPersistenceKey(@NonNull FirebaseApp app) {
return app.getPersistenceKey();
}

public static String getPersistenceKey(String name, FirebaseOptions options) {
return FirebaseApp.getPersistenceKey(name, options);
}

public static <T extends FirebaseService> T getService(
@NonNull FirebaseApp app, @NonNull String id, @NonNull Class<T> type) {
return type.cast(app.getService(id));
Expand All @@ -70,7 +62,8 @@ public static ThreadFactory getThreadFactory(@NonNull FirebaseApp app) {
return app.getThreadFactory();
}

public static <T> Task<T> submitCallable(@NonNull FirebaseApp app, @NonNull Callable<T> command) {
public static <T> ApiFuture<T> submitCallable(
@NonNull FirebaseApp app, @NonNull Callable<T> command) {
return app.submit(command);
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/google/firebase/ThreadManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ final void releaseFirebaseExecutors(
* {@link #getThreadFactory()} method.
*
* @param app A {@link FirebaseApp} instance.
* @return A non-null {@link ExecutorService} instance.
* @return A non-null <code>ExecutorService</code> instance.
*/
@NonNull
protected abstract ExecutorService getExecutor(@NonNull FirebaseApp app);
Expand Down
Loading