How to send one to one message using Firebase Messaging
Warning There is a very important reason why we don't mention this approach anywhere. This exposes your server key in the APK that
you put on every client device. It can (and thus will) be taken from
there and may lead to abuse of your project. I highly recommend
against taking this approach, except for apps that you only put on
your own devices. – Frank van Puffelen
Ok, so the answer by Frank was correct that Firebase
does not natively support device to device messaging. However there's one loophole in that. The Firebase server doesn't identify whether you have send the request from an actual server or are you doing it from your device.
So all you have to do is send a Post Request
to Firebase
's messaging server along with the Server Key. Just keep this in mind that the server key is not supposed to be on the device, but there's no other option if you want device-to-device messaging using Firebase Messaging.
I am using OkHTTP instead of default way of calling the Rest API. The code is something like this -
public static final String FCM_MESSAGE_URL = "https://fcm.googleapis.com/fcm/send";
OkHttpClient mClient = new OkHttpClient();
public void sendMessage(final JSONArray recipients, final String title, final String body, final String icon, final String message) {
new AsyncTask<String, String, String>() {
@Override
protected String doInBackground(String... params) {
try {
JSONObject root = new JSONObject();
JSONObject notification = new JSONObject();
notification.put("body", body);
notification.put("title", title);
notification.put("icon", icon);
JSONObject data = new JSONObject();
data.put("message", message);
root.put("notification", notification);
root.put("data", data);
root.put("registration_ids", recipients);
String result = postToFCM(root.toString());
Log.d(TAG, "Result: " + result);
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
try {
JSONObject resultJson = new JSONObject(result);
int success, failure;
success = resultJson.getInt("success");
failure = resultJson.getInt("failure");
Toast.makeText(getCurrentActivity(), "Message Success: " + success + "Message Failed: " + failure, Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getCurrentActivity(), "Message Failed, Unknown error occurred.", Toast.LENGTH_LONG).show();
}
}
}.execute();
}
String postToFCM(String bodyString) throws IOException {
RequestBody body = RequestBody.create(JSON, bodyString);
Request request = new Request.Builder()
.url(FCM_MESSAGE_URL)
.post(body)
.addHeader("Authorization", "key=" + SERVER_KEY)
.build();
Response response = mClient.newCall(request).execute();
return response.body().string();
}
I hope Firebase will come with a better solution in future. But till then, I think this is the only way. The other way would be to send topic message or group messaging. But that was not in the scope of the question.
Update:
The JSONArray is defined like this -
JSONArray regArray = new JSONArray(regIds);
regIds is a String array of registration ids, you want to send this message to. Keep in mind that the registration ids must always be in an array, even if you want it to send to a single recipient.
How to send FirebaseMessaging dynamically to all users when one action is done - Flutter?
You can do this using a cloud function. Either by calling the function from your app when the publication is created, or by having the cloud function listen for a new document. See this Medium post for some ideas: https://medium.com/@jerinamathews/send-firebase-cloud-messaging-fcm-to-a-topic-using-cloud-function-when-realtime-database-value-fa78fa758549
Update
Based on your update, I suggest you look at using a 'Topic' rather than a specific token (that applies to only one device). To use a Topic you need to ensure all users automatically subscribe to the chosen topic when they open the app (they can subscribe to the same topic each time, it has no negative impact). FCM maintains a list of subscribed device tokens against the topic.
I haven't used topic via an http post so I cannot confirm it is possible but I am assuming if you can send to a token you must be able to send to a topic.
Push firebase notification to one client
Firebase Cloud Messaging also allows you to send a notification to a single client, as long as you know the FCM token of that client. For example see the section on sending a message to a token using the Composer in the Firebase console, and sending a message to an individual device using the Admin SDK, and sending a message to an individual device using the HTTP REST API.
But FCM does not allow directly sending notification from once client to another. You will always needs to send the downstream messages from a trusted environment, such as the Composer in the Firebase console, your development machine, a server you control, or Cloud Functions.For more on this, see:
- How to send one to one message using Firebase Messaging
- How to send device to device messages using Firebase Cloud Messaging?
- Diego's answer here
- probably many more of these search results
How to send two Recurring Cloud Message every week one after another and repeat again from Firebase Console?
In the firebase dashboard, you can schedule the messages. Follow the steps in the dashboard and then click on Scheduling and click on Custom to be able to send a message one Monday and Tuesday.
Related Topics
Android Marshmallow Request Permission
How to Get the Android Device'S Primary E-Mail Address
How to Execute Dex: Multiple Dex Files Define Lcom/Myapp/R$Array;
Determine If the Device Is a Smartphone or Tablet
How to Listen For a Webview Finishing Loading a Url
Synchronise Scrollview Scroll Positions - Android
How to Do Something Like a Flowlayout in Android
How to Convert a Base64 String into a Bitmap Image to Show It in a Imageview
How to Stop Edittext from Gaining Focus When an Activity Starts in Android
How to Change an Application Icon Programmatically in Android
How to Format Date and Time in Android
Viewpager and Fragments - What's the Right Way to Store Fragment'S State
Android: How to Get String from Resources Using Its Name
How to Completely Uninstall Android Studio from Windows(V10)