Skip to content

Added FCM Root URL in FirebaseOptions #803

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
31 changes: 31 additions & 0 deletions src/main/java/com/google/firebase/FirebaseOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public GoogleCredentials get() {
};

private final String databaseUrl;
private final String fcmRootUrl;
private final String storageBucket;
private final Supplier<GoogleCredentials> credentialsSupplier;
private final Map<String, Object> databaseAuthVariableOverride;
Expand Down Expand Up @@ -101,6 +102,11 @@ private FirebaseOptions(@NonNull final FirebaseOptions.Builder builder) {
} else {
this.serviceAccountId = null;
}
if (!Strings.isNullOrEmpty(builder.fcmRootUrl)) {
this.fcmRootUrl = builder.fcmRootUrl;
} else {
this.fcmRootUrl = null;
}
this.storageBucket = builder.storageBucket;
this.httpTransport = builder.httpTransport != null ? builder.httpTransport
: ApiClientUtils.getDefaultTransport();
Expand All @@ -124,6 +130,15 @@ public String getDatabaseUrl() {
return databaseUrl;
}

/**
* Returns the Fcm Root URL that is used for Fcm Messaging.
*
* @return The Fcm Messaging URL supplied via {@link Builder#setFcmRootUrl}.
*/
public String getFcmRootUrl() {
return fcmRootUrl;
}

/**
* Returns the name of the Google Cloud Storage bucket used for storing application data.
*
Expand Down Expand Up @@ -260,6 +275,7 @@ public static final class Builder {
private ThreadManager threadManager;
private int connectTimeout;
private int readTimeout;
private String fcmRootUrl;

/**
* Constructs an empty builder.
Expand Down Expand Up @@ -290,6 +306,7 @@ public Builder(FirebaseOptions options) {
connectTimeout = options.connectTimeout;
readTimeout = options.readTimeout;
firestoreOptions = options.firestoreOptions;
fcmRootUrl = options.fcmRootUrl;
}

/**
Expand All @@ -306,6 +323,20 @@ public Builder setDatabaseUrl(@Nullable String databaseUrl) {
return this;
}

/**
* Sets the Fcm Root URL to use for Fcm Messaging.
*
* <p>See <a href="https://firebase.google.com/docs/admin/setup#initialize_the_sdk">
* Initialize the SDK</a> for code samples and detailed documentation.
*
* @param fcmRootUrl The Fcm Root URL to use for Fcm Messaging.
* @return This <code>Builder</code> instance is returned so subsequent calls can be chained.
*/
public Builder setFcmRootUrl(@Nullable String fcmRootUrl) {
this.fcmRootUrl = fcmRootUrl;
return this;
}

/**
* Sets the name of the Google Cloud Storage bucket for reading and writing application data.
* This should be the full name of the bucket as listed in the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,17 @@
* A helper class for interacting with Firebase Cloud Messaging service.
*/
final class FirebaseMessagingClientImpl implements FirebaseMessagingClient {

private static final String FCM_URL = "https://fcm.googleapis.com/v1/projects/%s/messages:send";
private static final String FCM_ROOT_URL = "https://fcm.googleapis.com";
private static final String FCM_SEND_PATH = "v1/projects/%s/messages:send";
private static final String FCM_BATCH_PATH = "batch";

private static final Map<String, String> COMMON_HEADERS =
ImmutableMap.of(
"X-GOOG-API-FORMAT-VERSION", "2",
"X-Firebase-Client", "fire-admin-java/" + SdkUtils.getVersion());

private final String fcmSendUrl;
private final String fcmBatchUrl;
private final HttpRequestFactory requestFactory;
private final HttpRequestFactory childRequestFactory;
private final JsonFactory jsonFactory;
Expand All @@ -78,22 +80,33 @@ final class FirebaseMessagingClientImpl implements FirebaseMessagingClient {

private FirebaseMessagingClientImpl(Builder builder) {
checkArgument(!Strings.isNullOrEmpty(builder.projectId));
this.fcmSendUrl = String.format(FCM_URL, builder.projectId);
String fcmRootUrl = Strings.isNullOrEmpty(builder.fcmRootUrl) ? FCM_ROOT_URL :
builder.fcmRootUrl;
this.fcmSendUrl = String.format(String.format(
"%s/%s", fcmRootUrl, FCM_SEND_PATH),
builder.projectId);
this.fcmBatchUrl = String.format("%s/%s", fcmRootUrl, FCM_BATCH_PATH);
this.requestFactory = checkNotNull(builder.requestFactory);
this.childRequestFactory = checkNotNull(builder.childRequestFactory);
this.jsonFactory = checkNotNull(builder.jsonFactory);
this.responseInterceptor = builder.responseInterceptor;
this.errorHandler = new MessagingErrorHandler(this.jsonFactory);
this.httpClient = new ErrorHandlingHttpClient<>(requestFactory, jsonFactory, errorHandler)
.setInterceptor(responseInterceptor);
this.batchClient = new MessagingBatchClient(requestFactory.getTransport(), jsonFactory);
this.batchClient = new MessagingBatchClient(requestFactory.getTransport(),
jsonFactory, fcmRootUrl);
}

@VisibleForTesting
String getFcmSendUrl() {
return fcmSendUrl;
}

@VisibleForTesting
String getFcmBatchUrl() {
return fcmBatchUrl;
}

@VisibleForTesting
HttpRequestFactory getRequestFactory() {
return requestFactory;
Expand Down Expand Up @@ -139,7 +152,7 @@ private BatchResponse sendBatchRequest(
return new BatchResponseImpl(callback.getResponses());
} catch (HttpResponseException e) {
OutgoingHttpRequest req = new OutgoingHttpRequest(
HttpMethods.POST, MessagingBatchClient.FCM_BATCH_URL);
HttpMethods.POST, fcmBatchUrl);
IncomingHttpResponse resp = new IncomingHttpResponse(e, req);
throw errorHandler.handleHttpResponseException(e, resp);
} catch (IOException e) {
Expand Down Expand Up @@ -193,6 +206,7 @@ static FirebaseMessagingClientImpl fromApp(FirebaseApp app) {
.setRequestFactory(ApiClientUtils.newAuthorizedRequestFactory(app))
.setChildRequestFactory(ApiClientUtils.newUnauthorizedRequestFactory(app))
.setJsonFactory(app.getOptions().getJsonFactory())
.setFcmRootUrl(app.getOptions().getFcmRootUrl())
.build();
}

Expand All @@ -207,9 +221,15 @@ static final class Builder {
private HttpRequestFactory childRequestFactory;
private JsonFactory jsonFactory;
private HttpResponseInterceptor responseInterceptor;
private String fcmRootUrl;

private Builder() { }

Builder setFcmRootUrl(String fcmRootUrl) {
this.fcmRootUrl = fcmRootUrl;
return this;
}

Builder setProjectId(String projectId) {
this.projectId = projectId;
return this;
Expand Down Expand Up @@ -319,22 +339,17 @@ private MessagingServiceErrorResponse safeParse(String response) {

private static class MessagingBatchClient extends AbstractGoogleJsonClient {

private static final String FCM_ROOT_URL = "https://fcm.googleapis.com";
private static final String FCM_BATCH_PATH = "batch";
private static final String FCM_BATCH_URL = String.format(
"%s/%s", FCM_ROOT_URL, FCM_BATCH_PATH);

MessagingBatchClient(HttpTransport transport, JsonFactory jsonFactory) {
super(new Builder(transport, jsonFactory));
MessagingBatchClient(HttpTransport transport, JsonFactory jsonFactory, String fcmRootUrl) {
super(new Builder(transport, jsonFactory, fcmRootUrl));
}

private MessagingBatchClient(Builder builder) {
super(builder);
}

private static class Builder extends AbstractGoogleJsonClient.Builder {
Builder(HttpTransport transport, JsonFactory jsonFactory) {
super(transport, jsonFactory, FCM_ROOT_URL, "", null, false);
Builder(HttpTransport transport, JsonFactory jsonFactory, String fcmRootUrl) {
super(transport, jsonFactory, fcmRootUrl, "", null, false);
setBatchPath(FCM_BATCH_PATH);
setApplicationName("fire-admin-java");
}
Expand Down
5 changes: 5 additions & 0 deletions src/test/java/com/google/firebase/FirebaseOptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
public class FirebaseOptionsTest {

private static final String FIREBASE_DB_URL = "https://mock-project.firebaseio.com";
private static final String FIREBASE_FCM_URL = "https://localhost";
private static final String FIREBASE_STORAGE_BUCKET = "mock-storage-bucket";
private static final String FIREBASE_PROJECT_ID = "explicit-project-id";

Expand All @@ -53,6 +54,7 @@ public class FirebaseOptionsTest {
.setStorageBucket(FIREBASE_STORAGE_BUCKET)
.setProjectId(FIREBASE_PROJECT_ID)
.setCredentials(TestUtils.getCertCredential(ServiceAccount.EDITOR.asStream()))
.setFcmRootUrl(FIREBASE_FCM_URL)
.build();

private static final ThreadManager MOCK_THREAD_MANAGER = new ThreadManager() {
Expand Down Expand Up @@ -88,8 +90,10 @@ public void createOptionsWithAllValuesSet() throws IOException {
.setConnectTimeout(30000)
.setReadTimeout(60000)
.setFirestoreOptions(firestoreOptions)
.setFcmRootUrl(FIREBASE_FCM_URL)
.build();
assertEquals(FIREBASE_DB_URL, firebaseOptions.getDatabaseUrl());
assertEquals(FIREBASE_FCM_URL, firebaseOptions.getFcmRootUrl());
assertEquals(FIREBASE_STORAGE_BUCKET, firebaseOptions.getStorageBucket());
assertEquals(FIREBASE_PROJECT_ID, firebaseOptions.getProjectId());
assertSame(jsonFactory, firebaseOptions.getJsonFactory());
Expand Down Expand Up @@ -183,6 +187,7 @@ public void checkToBuilderCreatesNewEquivalentInstance() {
assertNotSame(ALL_VALUES_OPTIONS, allValuesOptionsCopy);
assertEquals(ALL_VALUES_OPTIONS.getCredentials(), allValuesOptionsCopy.getCredentials());
assertEquals(ALL_VALUES_OPTIONS.getDatabaseUrl(), allValuesOptionsCopy.getDatabaseUrl());
assertEquals(ALL_VALUES_OPTIONS.getFcmRootUrl(), allValuesOptionsCopy.getFcmRootUrl());
assertEquals(ALL_VALUES_OPTIONS.getProjectId(), allValuesOptionsCopy.getProjectId());
assertEquals(ALL_VALUES_OPTIONS.getJsonFactory(), allValuesOptionsCopy.getJsonFactory());
assertEquals(ALL_VALUES_OPTIONS.getHttpTransport(), allValuesOptionsCopy.getHttpTransport());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@
public class FirebaseMessagingClientImplTest {

private static final String TEST_FCM_URL =
"https://fcm.googleapis.com/v1/projects/test-project/messages:send";
"https://fcm.googleapis.com/v1/projects/test-project/messages:send";
private static final String TEST_FCM_BATCH_URL = "https://fcm.googleapis.com/batch";

private static final List<Integer> HTTP_ERRORS = ImmutableList.of(401, 404, 500);

Expand Down Expand Up @@ -534,6 +535,7 @@ public void testFromApp() throws IOException {
FirebaseMessagingClientImpl client = FirebaseMessagingClientImpl.fromApp(app);

assertEquals(TEST_FCM_URL, client.getFcmSendUrl());
assertEquals(TEST_FCM_BATCH_URL, client.getFcmBatchUrl());
assertSame(options.getJsonFactory(), client.getJsonFactory());

HttpRequest request = client.getRequestFactory().buildGetRequest(
Expand Down