Reputation: 371
I've build a prototype lambda function that can send automated push notifications by querying my database based on the rules stored in Firebase. This function is scheduled to run everyday. By this function below, I am calling the Messaging object
private void sentAutomatedMessages(List<String> tokens, CardAbandonmentRule rule) {
for (String token : tokens) {
//Create Messaging object for every user that fits in this user
Messaging msgHandler = new Messaging(rule.getTitle(), rule.getMessage(), token);
try {
msgHandler.handleSingleDevicePush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The class definition and the methods for sending push notifications =>
public class Messaging {
private static final String PROJECT_ID = "<project_id>";
private static final String BASE_URL = "https://fcm.googleapis.com";
private static final String FCM_SEND_ENDPOINT = "/v1/projects/" + PROJECT_ID + "/messages:send";
private static final String MESSAGING_SCOPE = "https://www.googleapis.com/auth/firebase.messaging";
private static final String[] SCOPES = {MESSAGING_SCOPE};
private String title;
private String message;
private String token;
public Messaging(String title, String message, String token) {
this.title = title;
this.message = message;
this.token = token; // <FCM_token>
}
/**
* Retrieve a valid access token that can be use to authorize requests to the FCM REST
* API.
*
* @return Access token.
* @throws IOException
*/
private static String getAccessToken() throws IOException {
GoogleCredential googleCredential = GoogleCredential
.fromStream(new FileInputStream("<firebase_private_key.json>"))
.createScoped(Arrays.asList(SCOPES));
googleCredential.refreshToken();
return googleCredential.getAccessToken();
}
/**
* Create HttpURLConnection that can be used for both retrieving and publishing.
*
* @return Base HttpURLConnection.
* @throws IOException
*/
private static HttpURLConnection getConnection() throws IOException {
// [START use_access_token]
URL url = new URL(BASE_URL + FCM_SEND_ENDPOINT);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
String accessToken = getAccessToken();
System.out.println(accessToken);
httpURLConnection.setRequestProperty("Authorization", "Bearer " + accessToken);
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
return httpURLConnection;
// [END use_access_token]
}
/**
* Construct the body of a notification message request.
*
* @return JSON of notification message.
*/
private JsonObject buildNotificationMessage() {
JsonObject jNotification = new JsonObject();
jNotification.addProperty("title", this.title);
jNotification.addProperty("body", this.message);
JsonObject jMessage = new JsonObject();
jMessage.add("notification", jNotification);
jMessage.addProperty("token", this.token);
JsonObject jFcm = new JsonObject();
jFcm.add("message", jMessage);
return jFcm;
}
/**
* Send request to FCM message using HTTP.
*
* @param fcmMessage Body of the HTTP request.
* @throws IOException
*/
private static void sendtoSingleDevice(JsonObject fcmMessage) throws IOException {
HttpURLConnection connection = getConnection();
connection.setDoOutput(true);
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(fcmMessage.toString());
outputStream.flush();
outputStream.close();
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
String response = inputstreamToString(connection.getInputStream());
System.out.println("Message sent to Firebase for delivery, response:");
System.out.println(response);
} else {
System.out.println("Unable to send message to Firebase:");
String response = inputstreamToString(connection.getErrorStream());
System.out.println(response);
}
}
/**
* Public method to send Push Notification
*
* @throws IOException
*/
public void handleSingleDevicePush() throws IOException {
JsonObject notificationMessage = buildNotificationMessage();
sendtoSingleDevice(notificationMessage);
}
After I run the buildNotificationMessage()
, the object is formed like example below.
// Example Notification Message to send over HTTP
{
"message": {
"notification": {
"title": "title",
"body": "body"
},
"token": "<FCM_token>"
}
}
The response is =>
{ "name": "projects/<project_id>/messages/1542324302450893"}
I have to develop a dashboard for listing the sent messages, open rate and analytics. However, I need some guidance.
1 - What can I do with this name
given as a response from the FCM REST API ? I didn't see anything in the documentation for getting the details of messages.
2 - Is there a better way for sending bulk messages for multiple unique FCM token ? I see some stuff about device groups but Firebase says it's for a different purpose.
Typically, "group" refers a set of different devices that belong to a single user.
Thanks
Upvotes: 1
Views: 3670
Reputation: 371
After I've contacted with Firebase Support, they recommend me to use BigQuery by Google to see datasets for firebase messaging functionality.
After you enable the BigQuery integration in Firebase settings, you just need to go to BigQuery console.
A query like down below, will give you details for given message.
SELECT *
FROM `<project_name>.firebase_messaging.data`
WHERE
_PARTITIONTIME = TIMESTAMP('<date as YYYY-MM-DD>')
AND message_id = '<your message id>'
AND instance_id = '<your instance id>'
ORDER BY event_timestamp;
Link to see more examples and read about the BigQuery integration for FCM => Understanding the message delivery
Upvotes: 5