I'm working on an app that has firebase notifications, i followed through the firebase tutorial guides in order to how to send and receive notifications but I'm receiving 2 notifications on other devices instead of receiving 1 and receiving a notification from the sent device although that device shouldn't receive the notification that was sent from it
I saw other questions regarding uploading notifications twice but it didn't work for me
P.S: the notification is sent from a custom dialog that has title edit text and body edit text
here is the manifest:
<service
android:name=".MyFirebaseInstanceIDService"
android:exported="false">
<intent-filter>
<action
android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action
android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
I'm compiling these in the gradle:
compile 'com.google.firebase:firebase-core:10.0.0'
compile 'com.google.firebase:firebase-messaging:10.0.0'
Here's the code for the custom dialog:
builder = new AlertDialog.Builder(this);
final View view = View.inflate(this, R.layout.layout_send_notification, null);
builder.setView(view)
.setCancelable(true)
.setPositiveButton(getString(R.string.send), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
EditText editMessage = (EditText) view.findViewById(R.id.notification_message);
EditText editTitle = (EditText) view.findViewById(R.id.notification_title);
Calendar now = Calendar.getInstance();
int day = now.get(Calendar.DAY_OF_MONTH);
int month = now.get(Calendar.MONTH) + 1;
int year = now.get(Calendar.YEAR);
String message = editMessage.getText().toString().replace(' ', '_');
String title = editTitle.getText().toString().replace(' ', '_');
boolean cancel = false;
View focusView = null;
if (TextUtils.isEmpty(message)) {
editMessage.setError(getString(R.string.error_field_required));
focusView = editMessage;
cancel = true;
}
if (TextUtils.isEmpty(title)) {
editTitle.setError(getString(R.string.error_field_required));
focusView = editTitle;
cancel = true;
}
if (cancel)
focusView.requestFocus();
else {
RequestQueue queue = Volley.newRequestQueue(NotificationsActivity.this);
String url = "https://mysite.here/send_push.php?" +
"message=" + message +
"&title=" + title +
"&day=" + day +
"&month=" + month +
"&year=" + year;
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("send push response", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
queue.add(request);
}
}
})
.setNegativeButton(getString(R.string.button_cancel), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
sendNotificationDialog = builder.create();
here is the firebaseMessagingService:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
sendNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
}
private void sendNotification(String messageTitle, String messageBody) {
Intent intent = new Intent(this, SplashActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setSmallIcon(R.drawable.ic_stat_spe_bau)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 , notificationBuilder.build());
}
here is the firebaseInstanceIDService:
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d("firebase ID", refreshedToken);
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token) {
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
String url = "https://mysite.here/insertFCM_ID.php?fcmID=" + token;
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("fcm response", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
queue.add(request);
}
send_push.php code:
<?php
header("Content-type: application/json, charset=UTF-8");
require('db.php');
$db = mysqli_connect($host, $username, $password) or die('Could not connect');
mysqli_select_db($db, $db_name) or die('');
$message = $_GET['message'];
$title = $_GET['title'];
$day = $_GET['day'];
$month = $_GET['month'];
$year = $_GET['year'];
$server_key = "somekey";
$sql = 'select fcm_token from fcm_info';
$result = mysqli_query($db, $sql) or print("Error");
$key = array();
while ($row = mysqli_fetch_assoc($result)) {
$key[] = $row;
}
$headers = array(
'Authorization: key=' . $server_key,
'Content-Type: application/json'
);
$single = "";
foreach($key as $value) {
$single = $value['fcm_token'];
$fields = array(
'to' => $single,
'notification' => array(
'title' => str_replace("_", " ", $title),
'body' => str_replace("_", " ", $message),
'vibrate' => 1,
'sound' => 1
)
);
$payload = json_encode($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$result = curl_exec($ch);
}
mysqli_query($db, "INSERT INTO notifications (title, body, day, month, year) VALUES ('$title', '$message', '$day', '$month', '$year')");
mysqli_close($db);
echo $result;
?>
i tried a lot of ways in order to find where the problem is but i couldn't know what it is
if more information is needed i will re-edit this to add those required information
Make comment line in your onMessageReceived event:
//sendNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
}
Try again after you make this change in your firebaseInstanceIDService class. It should be ok.
If you want to use only Downstream messages, you need to decide your message type. Data messages or notifications. You also need to manage 3 situations of your app on the device: Foreground, Background and Killed. Data messages are always trigger onMessageReceived event on your Service. This is different when you send notification message. I suggest you sending Data messages as Post requests. You don't have any problem now. You are sending Post request to 'https://fcm.googleapis.com/fcm/send' URL via Volley and you are sending a notification. Then your service is receiving your notification and create another one. It is very normal to receive 2 notifications, because your code is generating 2 notification. I told you make comment line and test it.
You can save the message-id in a variable then when a new message received twice, the first message-id will be saved in this variable and when it called twice the second time you will check if exists in your variable or not .. for example
String savedMessageId = "";
public void setupFCM() {
if (savedMessageId != remoteMessage.messageId)
savedMessageId = remoteMessage.messageId;
else
return;
// your code ...
}
Related
I am working on an android chat app using firebase. Everything works fine except push notification. I have googled and read almost every post concerning the issue but still haven't figured out the solution!
Issue: On a fresh installation of the app to the device! I get the notification (ONLY ONCE FIRST TIME) then after that, there is no notification displayed whatsoever. Volley returns a success message "Multicast id remains the same for each success message and even the message-id remains the same for each success message" wondering it has to do with the problem! please have a look at the below code:
1) MY PHP SCRIPT RUNNING ON MY OWN WEB ADDRESS (APP SERVER):
<?php
define( 'API_ACCESS_KEY', 'AAAAeaFcZdA:APA91bFqhLc..............' );
$token = $_GET["token"];
$title = $_POST["title"];
$notification = $_POST["message"];
$msg =
[
'message' => $notification,
'title' => $title,
];
$fields =
[
'to' => $token,
'data' => $msg
];
$headers =
[
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
];
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close( $ch );
echo $result;
?>
2) My MessagingService (Firebase) to get Notifications, Since I get the first notification, I believe its configured properly!
public class MessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Timber.i("From: " + remoteMessage.getFrom());
//Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Timber.i("Message data payload: " + remoteMessage.getData());
Map<String, String> data = remoteMessage.getData();
sendNotification(data);
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Timber.i("Message Notification Body: " + remoteMessage.getNotification().getBody());
Map<String, String> data = remoteMessage.getData();
sendNotification(data);
}
Map<String, String> data = remoteMessage.getData();
sendNotification(data);
}
#Override
public void onNewToken(#NonNull String token) {
Timber.i("MyToken: " + token);
sendRegistrationToServer(token);
}
private void sendRegistrationToServer(String token) {
// TODO: Implement this method to send token to your app server.
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference usersdRef = database.getReference("users");
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
usersdRef.child(user.getUid()).child("tokens").setValue(token);
}
}
private void sendNotification(Map<String, String> messageBody) {
String myTitle = messageBody.get("title");
final int not_nu = generateRandom();
Intent intent = new Intent(this, ChatMessageActivity.class);
intent.putExtra("username", myTitle);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
ChatUserModel.chatWith = myTitle;
PendingIntent pendingIntent = PendingIntent.getActivity(this, not_nu /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = getString(R.string.notification_channel_id);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.marker)
.setContentTitle(messageBody.get("title"))
.setContentText(messageBody.get("message"))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(not_nu /* ID of notification */, notificationBuilder.build());
}
public int generateRandom() {
Random random = new Random();
return random.nextInt(9999 - 1000) + 1000;
}}
3) My Chat Activity where I am sending the message to another user.
getOtherToken = other user token id to whom I will send the message
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String messageText = messageArea.getText().toString();
SimpleDateFormat sdf = new SimpleDateFormat("dd.MMM.yyyy", Locale.getDefault());
String currentDate = sdf.format(new Date());
String currentTime = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());
if (!messageText.equals("")) {
Map<String, String> map = new HashMap<String, String>();
map.put("message", messageText);
map.put("user", user.getDisplayName());
map.put("timetoshow", currentTime);
map.put("dateStamp", currentDate);
usersmRef.child(reference1).push().setValue(map);
usersmRef.child(reference2).push().setValue(map);
messageArea.setText("");
sendNotificationToappServer(getOtherToken, user.getDisplayName(), messageText);
Timber.i("GetOtherTOken: " + user.getDisplayName() + " | " + getOtherToken + " | " + messageText);
}
}
});
4) My Volley Method in the Same ChatActivity.java as above where I send String Request to my App Server, the token here is of the user who will receive the message!
public void sendNotificationToappServer(String token, String title, String notification) {
String SERVER_ADDRESS = "https://www.mywebsite/notification.php?token=";
RequestQueue requestQueue;
// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());
// Instantiate the RequestQueue with the cache and network.
requestQueue = new RequestQueue(cache, network);
// Start the queue
requestQueue.start();
StringRequest stringRequest = new StringRequest(Request.Method.POST, SERVER_ADDRESS + token,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(ChatMessageActivity.this, response, Toast.LENGTH_LONG).show();
Timber.i("Volley: %s", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ChatMessageActivity.this, error.toString(), Toast.LENGTH_LONG).show();
Timber.i("Volley Error: " + error.toString());
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("title", title);
params.put("message", notification);
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
};
requestQueue.add(stringRequest);
}
5) My Volley Response recorded in Android Studio which is a success, For the first time, it delivers push notification but not after that until fresh install!
Anything if required other than above! please let me know. Fingers crossed!
I was able to fix the issue! Well, I found out the problem was cache management due to volley. Before posting a new queue request, clearing the cache will fix the issue!
queue.getCache().clear();
Also, I preferred using singleton class for Volley. Here is the updated code for sendNotificationToappServer method above:
public void sendNotificationToappServer(String token, String title, String notification) {
String SERVER_ADDRESS = "https://www.mywebsite/notification.php?token=";
// Get a RequestQueue
RequestQueue queue = MySingleton.getInstance(ChatMessageActivity.this).
getRequestQueue();
StringRequest stringRequest = new StringRequest(Request.Method.POST, SERVER_ADDRESS + token,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(ChatMessageActivity.this, response, Toast.LENGTH_LONG).show();
Timber.i("Volley: %s", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ChatMessageActivity.this, error.toString(), Toast.LENGTH_LONG).show();
Timber.i("Volley Error: " + error.toString());
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("title", title);
params.put("message", notification);
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
};
queue.getCache().clear();
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(stringRequest);
}
The PHP code in the question above works perfectly! so if you are looking for PHP script for firebase Cloud messaging App server for one on one messaging, go for it!
I am always getting an error on sending notification from android device in logcat I have tried so many times but nothing getting:
{"multicast_id":5162718122421221171,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
Here is my android code for sending message I am sending userABC topic in the topic section.
public void SendNotification(String Title, String Message){
NOTIFICATION_TITLE = Title;
NOTIFICATION_MESSAGE = Message;
JSONObject notification = new JSONObject();
JSONObject notifcationBody = new JSONObject();
try {
notifcationBody.put("title", NOTIFICATION_TITLE);
notifcationBody.put("message", NOTIFICATION_MESSAGE);
notification.put("to", TOPIC);
notification.put("data", notifcationBody);
} catch (JSONException e) {
Log.e(TAG, "onCreate: " + e.getMessage() );
}
sendNotification(notification);
}
private void sendNotification(JSONObject notification) {
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(FCM_API, notification,
new com.android.volley.Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i(TAG, "onResponse: " + response.toString());
}
},
new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "Request error", Toast.LENGTH_LONG).show();
Log.i(TAG, "onErrorResponse: Didn't work");
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("Authorization", serverKey);
params.put("Content-Type", contentType);
return params;
}
};
MySingleton.getInstance(getActivity().getApplicationContext()).addToRequestQueue(jsonObjectRequest);
}
Here is my FirebaseInstanceIDService.java class
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "mFirebaseIIDService";
private static final String SUBSCRIBE_TO = "userABC";
#Override
public void onTokenRefresh() {
/*
This method is invoked whenever the token refreshes
OPTIONAL: If you want to send messages to this application instance
or manage this apps subscriptions on the server side,
you can send this token to your server.
*/
String token = FirebaseInstanceId.getInstance().getToken();
// Once the token is generated, subscribe to topic with the userId
FirebaseMessaging.getInstance().subscribeToTopic(SUBSCRIBE_TO);
Log.i(TAG, "onTokenRefresh completed with token: " + token);
sendRegistrationToServer(token);
}
private void sendRegistrationToServer(String token) {
// send token to web service ??
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("server/saving-data/IDs");
// then store your token ID
ref.push().setValue(token);
}
}
Here is my FirebaseMessagingService.java class
public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
private final String ADMIN_CHANNEL_ID ="admin_channel";
#Override
public void onNewToken(String token) {
Log.d("TAG", "Refreshed token: " + token);
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d("THIS", "Refreshed token: " + refreshedToken);
FirebaseMessaging.getInstance().subscribeToTopic("userABC");
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token) {
// send token to web service ??
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("server/saving-data/IDs");
// then store your token ID
ref.push().setValue(token);
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
final Intent intent = new Intent(this, MainActivity.class);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
int notificationID = new Random().nextInt(3000);
/*
Apps targeting SDK 26 or above (Android O) must implement notification channels and add its notifications
to at least one of them. Therefore, confirm if version is Oreo or higher, then setup notification channel
*/
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
setupChannels(notificationManager);
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this , 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Bitmap largeIcon = BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher);
Uri notificationSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, ADMIN_CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(largeIcon)
.setContentTitle(remoteMessage.getData().get("title"))
.setContentText(remoteMessage.getData().get("message"))
.setAutoCancel(true)
.setSound(notificationSoundUri)
.setContentIntent(pendingIntent);
//Set notification color to match your app color template
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
notificationBuilder.setColor(getResources().getColor(R.color.colorPrimaryDark));
}
notificationManager.notify(notificationID, notificationBuilder.build());
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void setupChannels(NotificationManager notificationManager){
CharSequence adminChannelName = "New notification";
String adminChannelDescription = "Device to devie notification";
NotificationChannel adminChannel;
adminChannel = new NotificationChannel(ADMIN_CHANNEL_ID, adminChannelName, NotificationManager.IMPORTANCE_HIGH);
adminChannel.setDescription(adminChannelDescription);
adminChannel.enableLights(true);
adminChannel.setLightColor(Color.RED);
adminChannel.enableVibration(true);
if (notificationManager != null) {
notificationManager.createNotificationChannel(adminChannel);
}
}
}
FirebaseInstanceIdService is deprecated now.
So you can change your registration logic as below
FcmRegistrationManager.java
public class FcmRegistrationManager {
private static final String TAG = "FcmRegistrationManager"
/*This is async call*/
public void registerWithFcm(){
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = task.getResult().getToken();
Log.d(TAG, msg);
sendRegistrationToServer(token)
}
});
}
private void sendRegistrationToServer(String token) {
// send token to web service ??
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("server/saving-data/IDs");
// then store your token ID
ref.push().setValue(token);
}
}
No change for sendNotification() and FirebaseMessagingService class.
More reference : https://firebase.google.com/docs/cloud-messaging/android/client
Let me still not working, I will share you working code.
I have two apps that use FCM, Client and Worker app. Client is sending the message:
String jsonLatLng = new Gson().toJson(new LatLng(Common.placeLatLng.latitude, Common.placeLatLng.longitude));
String clientToken = FirebaseInstanceId.getInstance().getToken();
Notification notification = new Notification(clientToken, jsonLatLng);
Sender content = new Sender(tokenId, notification);
mFCMService.sendMessage(content)
.enqueue(new Callback<FCMResponse>() {
#Override
public void onResponse(Call<FCMResponse> call, Response<FCMResponse> response) {
if(response.body().success == 1) {
Toast.makeText(HomeActivity.this, "Request sent.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(HomeActivity.this, "Request not sent.", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<FCMResponse> call, Throwable t) {
}
});
Wherein Notification.java is
public class Notification {
public String title;
public String body;
...
}
Sender.java is
public class Sender {
public String to;
public Notification notification;
...
}
And with the Worker app, it receives:
public class MyFirebaseMessaging extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Convert lat lng
LatLng clientLocation = new Gson().fromJson(remoteMessage.getNotification().getBody(), LatLng.class);
Intent intent = new Intent(getBaseContext(), NotificationActivity.class);
intent.putExtra("lat", clientLocation.latitude);
intent.putExtra("lng", clientLocation.longitude);
intent.putExtra("client", remoteMessage.getNotification().getTitle());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
These codes work perfectly fine, however, I need to add more details, specifically, I want to send data from 2 String variables, serviceFee & serviceType over to the Worker app. I tried modifying the body of the Notification wherein I created a class called Body with three variables (jsonLatLng, serviceFee, serviceType), but I can't figure out how the worker will be able to get the data of Body or if that's even possible. Please help. Thank you! :)
I've create push notification for my android app, it's work when I try to send it from firebase console. Now what I want is make a push notification when user click on register then show the notification for other users.
I've search in google but didn't find one of the example. The goals is to notif other user that there are new user register in my app.
Thanks for help
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMessagingService";
public static final int ID_SMALL_NOTIFICATION = 235;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// ...
// TODO(developer): Handle FCM messages here.
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
sendNotification("Hi ini isinya");
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG,"Message Notification Title" + remoteMessage.getNotification().getTitle());
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, ID_SMALL_NOTIFICATION, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = "fcm_default_channel";
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.icon)
.setContentTitle("FCM Message")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(ID_SMALL_NOTIFICATION, notificationBuilder.build());
}
}
I didn't get what you mean but you can use Volly Json object request
First you need to copy your server key from Firebase Console, open up Firebase Console and choose your project
Second add Volley dependency in your project
compile 'com.mcxiaoke.volley:library:1.0.19'
then you can add this code to push
private void sendFCMPush() {
String SERVER_KEY = YOUR_SERVER_KEY;
String msg = "this is test message";
String title = "my title";
String token = FCM_TOKEN;
JSONObject obj = null;
JSONObject objData = null;
JSONObject dataobjData = null;
try {
obj = new JSONObject();
objData = new JSONObject();
objData.put("body", msg);
objData.put("title", title);
objData.put("sound", "default");
objData.put("icon", "icon_name"); // icon_name
objData.put("tag", token);
objData.put("priority", "high");
dataobjData = new JSONObject();
dataobjData.put("text", msg);
dataobjData.put("title", title);
obj.put("to", token);
//obj.put("priority", "high");
obj.put("notification", objData);
obj.put("data", dataobjData);
Log.e("return here>>", obj.toString());
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, Constants.FCM_PUSH_URL, obj,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.e("True", response + "");
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("False", error + "");
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Authorization", "key=" + SERVER_KEY);
params.put("Content-Type", "application/json");
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
int socketTimeout = 1000 * 60;// 60 seconds
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
jsObjRequest.setRetryPolicy(policy);
requestQueue.add(jsObjRequest);
}
Hope this help
You want to send a push when one user clicks to register to everyone else who have already registered, right?.
You need to make a HTTP POST request to this address:
https://fcm.googleapis.com/fcm/send
With a header called "Authorization" with value like this "key=AIza...".
So in the body of the request you send a JSON like this.
{
"to": "/topics/foo-bar",
"data": {
"message": "This is a Firebase Cloud Messaging Topic Message!",
}
}
And then you need to create a topic and subscribe the device to the same topic.
FirebaseMessaging.getInstance().subscribeToTopic("foo-bar");
That should work just fine.
I know Firebase contains a section to send notifications, writing your message in console, but I want to get the values from a table to display the values in a notification. Is this possible?
This is how i did:
//Firebase Context
Firebase.setAndroidContext(this);
//URL database firebase
Firebase ref = new Firebase(Config.FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {
//DataSnapshot para leer datos de un bd
#Override
public void onDataChange(DataSnapshot snapshot) {
//Get Actual Value(getchildren)
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
//Getting the data from snapshot
Person person = postSnapshot.getValue(Person.class);
//Intent(Get components GUI)
Intent intent = new Intent();
//Allow External Application(PendingIntent)
PendingIntent pInent = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
//Notificacion
Notification noti = new Notification.Builder(MainActivity.this)
//Propiedades
.setContentTitle("Notificacion")
.setSound(Uri.EMPTY)
.setContentText("Nombre: "+person.getName()+"\t\tDireccion: "+person.getAddress())
.setSmallIcon(R.mipmap.bus)
.setContentIntent(pInent).getNotification();
//Cancel notification
noti.flags = Notification.FLAG_AUTO_CANCEL;
//Get Notification
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(1, noti);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});