Add sender identifier to configuration
Allow a client to retrieve the FCM sender id, so it can generate a
token for this server.
Change-Id: If27a89dc34bb6ffab0b057a7ef58cbdd9f676a4c
Signed-off-by: Jorge Ruesga <j.ruesga.criado@gmail.com>
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/ApiModule.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/ApiModule.java
index f240abc..7117d03 100644
--- a/src/main/java/com/ruesga/gerrit/plugins/fcm/ApiModule.java
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/ApiModule.java
@@ -16,6 +16,7 @@
package com.ruesga.gerrit.plugins.fcm;
import static com.google.gerrit.server.account.AccountResource.ACCOUNT_KIND;
+import static com.google.gerrit.server.config.ConfigResource.CONFIG_KIND;
import static com.ruesga.gerrit.plugins.fcm.server.DeviceResource.DEVICE_KIND;
import static com.ruesga.gerrit.plugins.fcm.server.TokenResource.TOKEN_KIND;
@@ -52,6 +53,7 @@
import com.ruesga.gerrit.plugins.fcm.handlers.TopicEditedEventHandler;
import com.ruesga.gerrit.plugins.fcm.server.DeleteToken;
import com.ruesga.gerrit.plugins.fcm.server.Devices;
+import com.ruesga.gerrit.plugins.fcm.server.GetCloudNotificationsConfigInfo;
import com.ruesga.gerrit.plugins.fcm.server.GetToken;
import com.ruesga.gerrit.plugins.fcm.server.PostToken;
import com.ruesga.gerrit.plugins.fcm.server.Tokens;
@@ -60,6 +62,7 @@
public class ApiModule extends RestApiModule {
+ public static final String CONFIG_ENTRY_POINT = "cloud-notifications";
public static final String DEVICES_ENTRY_POINT = "devices";
public static final String TOKEN_ENTRY_POINT = "tokens";
@@ -100,6 +103,8 @@
// Configure the Rest API
DynamicMap.mapOf(binder(), DEVICE_KIND);
DynamicMap.mapOf(binder(), TOKEN_KIND);
+ get(CONFIG_KIND, CONFIG_ENTRY_POINT).to(
+ GetCloudNotificationsConfigInfo.class);
child(ACCOUNT_KIND, DEVICES_ENTRY_POINT).to(Devices.class);
child(DEVICE_KIND, TOKEN_ENTRY_POINT).to(Tokens.class);
get(TOKEN_KIND).to(GetToken.class);
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/Configuration.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/Configuration.java
index e952af3..da01faa 100644
--- a/src/main/java/com/ruesga/gerrit/plugins/fcm/Configuration.java
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/Configuration.java
@@ -36,10 +36,12 @@
public static final String PROP_DATABASE_PATH = "databasePath";
public static final String PROP_SERVER_URL = "serverUrl";
public static final String PROP_SERVER_TOKEN = "serverToken";
+ public static final String PROP_SERVER_SENDER_ID = "serverSenderId";
public final String databasePath;
public final String serverToken;
public final String serverUrl;
+ public final String serverSenderId;
@Inject
public Configuration(
@@ -48,6 +50,7 @@
PluginConfig cfg = cfgFactory.getFromGerritConfig(pluginName);
this.databasePath = cfg.getString(PROP_DATABASE_PATH);
this.serverToken = cfg.getString(PROP_SERVER_TOKEN);
+ this.serverSenderId = cfg.getString(PROP_SERVER_SENDER_ID);
String serverUrl = cfg.getString(PROP_SERVER_URL);
if (serverUrl == null || serverUrl.isEmpty()) {
serverUrl = Configuration.DEFAULT_SERVER_URL;
@@ -60,6 +63,7 @@
}
public boolean isEnabled() {
- return this.serverToken != null && !this.serverToken.isEmpty();
+ return (this.serverToken != null && !this.serverToken.isEmpty()) &&
+ (this.serverSenderId != null && !this.serverSenderId.isEmpty());
}
}
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/InitStep.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/InitStep.java
index cffe676..f133a61 100644
--- a/src/main/java/com/ruesga/gerrit/plugins/fcm/InitStep.java
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/InitStep.java
@@ -47,8 +47,8 @@
String serverUrl = ui.readString(
Configuration.DEFAULT_SERVER_URL, "Firebase Server Url");
- String serverToken = ui.readString(
- "", "Firebase Server Token");
+ String serverToken = ui.readString("", "Firebase Server Token");
+ String serverSenderId = ui.readString("", "Firebase Server Sender Id");
String databasePath = ui.readString(
"", "Database path (leave empty for default)");
@@ -56,13 +56,19 @@
serverUrl = Configuration.DEFAULT_SERVER_URL;
}
cfg.setString("plugin", pluginName,
- Configuration.PROP_SERVER_TOKEN, serverUrl);
+ Configuration.PROP_SERVER_URL, serverUrl);
if (serverToken != null && serverToken.isEmpty()) {
cfg.unset("plugin", pluginName, Configuration.PROP_SERVER_TOKEN);
} else {
cfg.setString("plugin", pluginName,
Configuration.PROP_SERVER_TOKEN, serverToken);
}
+ if (serverSenderId != null && serverSenderId.isEmpty()) {
+ cfg.unset("plugin", pluginName, Configuration.PROP_SERVER_SENDER_ID);
+ } else {
+ cfg.setString("plugin", pluginName,
+ Configuration.PROP_SERVER_SENDER_ID, serverSenderId);
+ }
if (databasePath != null && databasePath.isEmpty()) {
cfg.unset("plugin", pluginName, Configuration.PROP_DATABASE_PATH);
} else {
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/rest/CloudNotificationsConfigInfo.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/rest/CloudNotificationsConfigInfo.java
new file mode 100644
index 0000000..79da843
--- /dev/null
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/rest/CloudNotificationsConfigInfo.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 Jorge Ruesga
+ *
+ * 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.ruesga.gerrit.plugins.fcm.rest;
+
+import com.google.gson.annotations.SerializedName;
+
+public class CloudNotificationsConfigInfo {
+ /**
+ * The Firebase Cloud server sender id.
+ */
+ @SerializedName("senderId") public String senderId;
+}
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/DeleteToken.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/DeleteToken.java
index b52cba3..7eee061 100644
--- a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/DeleteToken.java
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/DeleteToken.java
@@ -16,8 +16,10 @@
package com.ruesga.gerrit.plugins.fcm.server;
import com.google.gerrit.extensions.restapi.BadRequestException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.ruesga.gerrit.plugins.fcm.Configuration;
import com.ruesga.gerrit.plugins.fcm.DatabaseManager;
import com.ruesga.gerrit.plugins.fcm.server.DeleteToken.Input;
import com.google.gerrit.server.CurrentUser;
@@ -33,19 +35,27 @@
private final Provider<CurrentUser> self;
private final DatabaseManager db;
+ private final Configuration config;
@Inject
public DeleteToken(
Provider<CurrentUser> self,
- DatabaseManager db) {
+ DatabaseManager db,
+ Configuration config) {
super();
this.self = self;
this.db = db;
+ this.config = config;
}
@Override
public Response<?> apply(TokenResource rsrc, Input input)
- throws BadRequestException {
+ throws BadRequestException, ResourceNotFoundException {
+ // Check if plugin is configured
+ if (!config.isEnabled()) {
+ throw new ResourceNotFoundException("not configured!");
+ }
+
// Request are only valid from the current authenticated user
if (self.get() == null || self.get() != rsrc.getUser()) {
throw new BadRequestException("invalid account!");
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetCloudNotificationsConfigInfo.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetCloudNotificationsConfigInfo.java
new file mode 100644
index 0000000..5d40037
--- /dev/null
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetCloudNotificationsConfigInfo.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Jorge Ruesga
+ *
+ * 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.ruesga.gerrit.plugins.fcm.server;
+
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.config.ConfigResource;
+import com.ruesga.gerrit.plugins.fcm.Configuration;
+import com.ruesga.gerrit.plugins.fcm.rest.CloudNotificationsConfigInfo;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+public class GetCloudNotificationsConfigInfo
+ implements RestReadView<ConfigResource> {
+
+ private final Configuration config;
+
+ @Inject
+ public GetCloudNotificationsConfigInfo(Configuration config) {
+ super();
+ this.config = config;
+ }
+
+ @Override
+ public CloudNotificationsConfigInfo apply(ConfigResource rsrc)
+ throws ResourceNotFoundException {
+ // Check if plugin is configured
+ if (!config.isEnabled()) {
+ throw new ResourceNotFoundException("not configured!");
+ }
+
+ CloudNotificationsConfigInfo info = new CloudNotificationsConfigInfo();
+ info.senderId = this.config.serverSenderId;
+ return info;
+ }
+}
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetDevice.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetDevice.java
index e4113e6..00a7fce 100644
--- a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetDevice.java
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetDevice.java
@@ -18,6 +18,7 @@
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
+import com.ruesga.gerrit.plugins.fcm.Configuration;
import com.ruesga.gerrit.plugins.fcm.rest.CloudNotificationInfo;
import com.google.gerrit.server.CurrentUser;
import com.google.inject.Inject;
@@ -28,16 +29,26 @@
public class GetDevice implements RestReadView<DeviceResource> {
private final Provider<CurrentUser> self;
+ private final Configuration config;
@Inject
- public GetDevice(Provider<CurrentUser> self) {
+ public GetDevice(
+ Provider<CurrentUser> self,
+ Configuration config) {
super();
this.self = self;
+ this.config = config;
}
@Override
public CloudNotificationInfo apply(DeviceResource rsrc)
throws BadRequestException, ResourceNotFoundException {
+ // Check if plugin is configured
+ if (!config.isEnabled()) {
+ throw new ResourceNotFoundException("not configured!");
+ }
+
+ // Request are only valid from the current authenticated user
if (self.get() == null || self.get() != rsrc.getUser()) {
throw new BadRequestException("invalid account!");
}
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetToken.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetToken.java
index 0f9883c..d12613a 100644
--- a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetToken.java
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/GetToken.java
@@ -18,6 +18,7 @@
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
+import com.ruesga.gerrit.plugins.fcm.Configuration;
import com.ruesga.gerrit.plugins.fcm.DatabaseManager;
import com.ruesga.gerrit.plugins.fcm.rest.CloudNotificationInfo;
import com.google.gerrit.server.CurrentUser;
@@ -30,19 +31,28 @@
private final Provider<CurrentUser> self;
private final DatabaseManager db;
+ private final Configuration config;
@Inject
public GetToken(
Provider<CurrentUser> self,
- DatabaseManager db) {
+ DatabaseManager db,
+ Configuration config) {
super();
this.self = self;
this.db = db;
+ this.config = config;
}
@Override
public CloudNotificationInfo apply(TokenResource rsrc)
throws BadRequestException, ResourceNotFoundException {
+ // Check if plugin is configured
+ if (!config.isEnabled()) {
+ throw new ResourceNotFoundException("not configured!");
+ }
+
+ // Request are only valid from the current authenticated user
if (self.get() == null || self.get() != rsrc.getUser()) {
throw new BadRequestException("invalid account!");
}
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/ListDevices.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/ListDevices.java
index aca2b6b..4715715 100644
--- a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/ListDevices.java
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/ListDevices.java
@@ -18,26 +18,39 @@
import java.util.List;
import com.google.gerrit.extensions.restapi.BadRequestException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountResource;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
+import com.ruesga.gerrit.plugins.fcm.Configuration;
@Singleton
public class ListDevices implements RestReadView<AccountResource> {
+
private final Provider<CurrentUser> self;
+ private final Configuration config;
@Inject
- public ListDevices(Provider<CurrentUser> self) {
+ public ListDevices(
+ Provider<CurrentUser> self,
+ Configuration config) {
super();
this.self = self;
+ this.config = config;
}
@Override
public List<DeviceResource> apply(AccountResource rsrc)
- throws BadRequestException {
+ throws BadRequestException, ResourceNotFoundException {
+ // Check if plugin is configured
+ if (!config.isEnabled()) {
+ throw new ResourceNotFoundException("not configured!");
+ }
+
+ // Request are only valid from the current authenticated user
if (self.get() == null || self.get() != rsrc.getUser()) {
throw new BadRequestException("invalid account!");
}
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/ListTokens.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/ListTokens.java
index 159f8aa..af9012a 100644
--- a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/ListTokens.java
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/ListTokens.java
@@ -18,11 +18,13 @@
import java.util.List;
import com.google.gerrit.extensions.restapi.BadRequestException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.CurrentUser;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
+import com.ruesga.gerrit.plugins.fcm.Configuration;
import com.ruesga.gerrit.plugins.fcm.DatabaseManager;
import com.ruesga.gerrit.plugins.fcm.rest.CloudNotificationInfo;
@@ -31,19 +33,28 @@
private final Provider<CurrentUser> self;
private final DatabaseManager db;
+ private final Configuration config;
@Inject
public ListTokens(
Provider<CurrentUser> self,
- DatabaseManager db) {
+ DatabaseManager db,
+ Configuration config) {
super();
this.self = self;
this.db = db;
+ this.config = config;
}
@Override
public List<CloudNotificationInfo> apply(DeviceResource rsrc)
- throws BadRequestException {
+ throws BadRequestException, ResourceNotFoundException {
+ // Check if plugin is configured
+ if (!config.isEnabled()) {
+ throw new ResourceNotFoundException("not configured!");
+ }
+
+ // Request are only valid from the current authenticated user
if (self.get() == null || self.get() != rsrc.getUser()) {
throw new BadRequestException("invalid account!");
}
diff --git a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/PostToken.java b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/PostToken.java
index b2492a0..5349a81 100644
--- a/src/main/java/com/ruesga/gerrit/plugins/fcm/server/PostToken.java
+++ b/src/main/java/com/ruesga/gerrit/plugins/fcm/server/PostToken.java
@@ -21,7 +21,9 @@
import java.util.TimeZone;
import com.google.gerrit.extensions.restapi.BadRequestException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.ruesga.gerrit.plugins.fcm.Configuration;
import com.ruesga.gerrit.plugins.fcm.DatabaseManager;
import com.ruesga.gerrit.plugins.fcm.rest.CloudNotificationInfo;
import com.ruesga.gerrit.plugins.fcm.rest.CloudNotificationInput;
@@ -37,14 +39,17 @@
private final Provider<CurrentUser> self;
private final DatabaseManager db;
private final SimpleDateFormat formatter;
+ private final Configuration config;
@Inject
public PostToken(
Provider<CurrentUser> self,
- DatabaseManager db) {
+ DatabaseManager db,
+ Configuration config) {
super();
this.self = self;
this.db = db;
+ this.config = config;
formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
@@ -53,7 +58,12 @@
@Override
public CloudNotificationInfo apply(
DeviceResource rsrc, CloudNotificationInput input)
- throws BadRequestException {
+ throws BadRequestException, ResourceNotFoundException {
+ // Check if plugin is configured
+ if (!config.isEnabled()) {
+ throw new ResourceNotFoundException("not configured!");
+ }
+
// Request are only valid from the current authenticated user
if (self.get() == null || self.get() != rsrc.getUser()) {
throw new BadRequestException("invalid account!");
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index 619f0df..1c7e053 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -4,5 +4,5 @@
This is a Gerrit's plugin to send notifications using Firebase Cloud Messaging
to devices previously registered.
-Checkout the document fcm.md in this same folder, for an explanation about
-how it works.
+Checkout the document api.md in this same folder, for an explanation about
+the new api entrypoints.
diff --git a/src/main/resources/Documentation/fcm.md b/src/main/resources/Documentation/api.md
similarity index 84%
rename from src/main/resources/Documentation/fcm.md
rename to src/main/resources/Documentation/api.md
index dce5199..eb838ce 100644
--- a/src/main/resources/Documentation/fcm.md
+++ b/src/main/resources/Documentation/api.md
@@ -6,13 +6,37 @@
A client application can unregistered a device (and stop receiving notifications) from the Gerrit instance using the *Unregister Cloud Notification* method.
-Client applications must use a combintion of fcm device identifier + a unique local account token, so they can register to listen notification for different accounts on this Gerrit instance. Token must
+Client applications must use a combination of fcm device identifier + a unique local account token, so they can register to listen notification for different accounts on this Gerrit instance. Token must
REST API
--------
-This plugin addes new methods to the /accounts Gerrit REST Api entry point to allow a device to register/unregister to receive event notification in this gerrit instance.
+This plugin adds new methods to the /accounts Gerrit REST Api entry point to allow a device to register/unregister to receive event notification in this Gerrit instance.
+
+***
+
+**Get Cloud Notifications Config**
+
+`'GET /config/server/cloud-notifications'`
+
+Retrieve the cloud notifications server configuration of the Gerrit server instance.
+
+*Request*
+This method returns a *CloudNotificationsConfigInfo* entity (see below).
+
+ GET /config/server/cloud-notifications
+
+*Response*
+
+ HTTP1.1 200 OK
+ Content-Disposition: attachment
+ Content-Type: application/json; charset=UTF-8
+
+ )]}'
+ {
+ "senderId": "322112333"
+ }
***
@@ -20,7 +44,7 @@
`'GET /accounts/{account-id}/devices/{device-id}/tokens'`
-Retrieves a list of registered tokens by a device hold by the Gerrit server instance.
+Retrieve a list of registered tokens by a device hold by the Gerrit server instance.
*Request*
This request requires an authenticated call and only returns information if account-id is the authenticated account. This method returns a list of *CloudNotificationInfo* entities (see below).
@@ -50,7 +74,7 @@
`'GET /accounts/{account-id}/devices/{device-id}/tokens/{token}'`
-Retrieves a registered device information hold by the Gerrit server instance.
+Retrieve a registered device information hold by the Gerrit server instance.
*Request*
This request requires an authenticated call and only returns information if account-id is the authenticated account. This method returns a *CloudNotificationInfo* entity (see below).
@@ -128,6 +152,14 @@
***
+**CloudNotificationsConfigInfo**
+
+Entity with information about the cloud notifications server configuration.
+
+`senderId: The Firebase Cloud Messaging server identifier.`
+
+***
+
**CloudNotificationInfo**
Entity with information about a registered device.
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index f807f6f..52d6f83 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -12,20 +12,25 @@
```
[plugin "cloud-notifications"]
- serverUrl = https://fcm.googleapis.com/fcm/send
serverToken = <SERVER_API_KEY>
+ serverSenderId = <SERVER_SENDER_ID>
+ serverUrl = <https://fcm.googleapis.com/fcm/send>
databasePath = <DATABASE_LOCATION_PATH>
```
Plugin parameters
--------------------
-* serverUrl: The Firebase Cloud Messaging backend url.
-Default: https://fcm.googleapis.com/fcm/send
-
* serverToken: Your Firebase Cloud Messaging server token. You can
grab it from your Firebase project console, in Configuration > Cloud
Messaging > Server key
+* serverSenderId: Your Firebase Cloud Messaging server sender identifier.
+You can grab it from your Firebase project console, in Configuration > Cloud
+Messaging > Server Id
+
+* serverUrl: The Firebase Cloud Messaging backend url.
+Default: https://fcm.googleapis.com/fcm/send
+
* databasePath: The path to where to store the plugin database. Leave
empty to use the default path ($gerrit/data/cloud-notifications/cloud-notifications.h2.db)