I am using FCM to send notification for downloading a file in my android app. When my app is not running and i send FCM then I get all the notifications that I send earlier and new one continuously.
How to overcome this?
Here is my MyFirebaseMessagingService class.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d("data", "onMessageReceived: firebase called");
Map<String, String> data = remoteMessage.getData();
String url = data.get("file_url");
Intent broadcast_intent = new Intent();
broadcast_intent.putExtra(MainActivity.FIREBASE_URL, url); broadcast_intent.setAction(MainActivity.FIREBASE_URL_BROADCAST);
sendBroadcast(broadcast_intent);
}
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token) {
}
Related
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 had UrbanAirship implemented in version 1 of the app.
Now I extended FirebaseMessagingService in version 2 of the app.
I am not getting a call in onNewToken() to be able to send the token to my servers.
My boilerplate code looks like
AndroidManifest.xml
<service
android:name=".services.fcm.PushMessageReceiver"
android:enabled="true"
android:exported="true"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
and Receiver
public class PushMessageReceiver extends FirebaseMessagingService { ...
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
...
}
#Override
public void onNewToken(String s) {
Log.i(Config.LOGTAG, "######**** new token for fcm called");
Context ctx =ApplicationCustom.getContext();
SharedPreferences preferences = ctx.getSharedPreferences(Config.SHARED_PREFERENCES, Context.MODE_PRIVATE);
preferences.edit().putString(Config.SHARED_PREFS_DEVICE_TOKEN, s).apply();
Intent intent = new Intent(this, XmppConnectionService.class);
intent.setAction(XmppConnectionService.ACTION_FCM_TOKEN_REFRESH);
intent.putExtra("token", s);
startService(intent);
pushToServer();
}
public static void getToken() {
Log.i(Config.LOGTAG, "######**** get token for fcm called");
try {
Log.i(Config.LOGTAG, "######**** delete token for fcm called");
FirebaseInstanceId.getInstance().deleteInstanceId();
FirebaseInstanceId.getInstance().getInstanceId();
} catch (IOException e) {
e.printStackTrace();
Log.w(Config.LOGTAG, "######**** delete InstanceId failed", e);
}
FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(task
-> {
if (!task.isSuccessful()) {
Log.w(Config.LOGTAG, "getInstanceId failed", task.getException());
return;
}
Log.i(Config.LOGTAG, "######**** getInstanceId successful");
// Get new Instance ID token
String token = task.getResult().getToken();
Context ctx = ApplicationCustom.getContext();
SharedPreferences preferences = ctx.getSharedPreferences(Config.SHARED_PREFERENCES, Context.MODE_PRIVATE);
preferences.edit().putString(Config.SHARED_PREFS_DEVICE_TOKEN, token).apply();
pushToServer();
});
}
public void pushToServer(){
// Logic to push token to a server reading from preferences
}
}
Observations:
1) onNewToken never gets called for apps that are being updated.
2) new installs get a token
3) after I added a call to FirebaseInstanceId.getInstance().deleteInstanceId()
OnComplete does not get called either.
4) A call to getToken(senderId, "FCM") on real phones (not emulators) invariably results in
java.io.IOException: TOO_MANY_REGISTRATIONS
at com.google.firebase.iid.zzr.zza(Unknown Source:66)
at com.google.firebase.iid.zzr.zza(Unknown Source:79)
at com.google.firebase.iid.zzu.then(Unknown Source:4)
at com.google.android.gms.tasks.zzd.run(Unknown Source:5)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
how do I fix observation 1. Is it because the token has already been delivered to UrbanAirship that onNewToken does not get called?
Fyi getToken is called in a service onCreate() method.
implementation 'com.google.firebase:firebase-messaging:17.3.4'
you can get fcm token by this:-
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (task.isSuccessful()) {
String firebaseToken = task.getResult().getToken();
} else {
getFirebaseToken();
}
}
});
That's okay if your onNewToken() is not called. You can get the latest token already made by firebase for your device. onNewToken() is called on specific occasions.
The registration token may change when:
-The app deletes Instance ID
-The app is restored on a new device
-The user uninstalls/reinstall the app
-The user clears app data.
Do read the firebase documentation :
https://firebase.google.com/docs/cloud-messaging/android/client#retrieve-the-current-registration-token
And for your second query, deleteInstanceId is a blocking call, so you will have to do it in a background thread. like this,
new Thread(new Runnable() {
#Override
public void run() {
try {
FirebaseInstanceId.getInstance().deleteInstanceId();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
Some time onTokenRefresh() method call with some delay and it will generate token when new install happen that how its behave their for we need to implement functionality like below to overcome those issue maintain new user login also
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private String TAG = getClass().getName();
public static final String TOKEN_BROADCAST = "myfcmtokenbroadcast";
#Override
public void onTokenRefresh() {
//For registration of token
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//To displaying token on logcat
Log.d("TOKEN: ", refreshedToken);
//calling the method store token and passing token
getApplicationContext().sendBroadcast(new Intent(TOKEN_BROADCAST));
storeToken(refreshedToken);
}
private void storeToken(String token) {
//we will save the token in sharedpreferences later
SharedPrefManager.getInstance(getApplicationContext()).saveDeviceToken(token);
}
}
In your onCreate method in MainActivity class call this methord
private void registerFCMToken(){
registerReceiver(broadcastReceiver, new IntentFilter(MyFirebaseInstanceIDService.TOKEN_BROADCAST));
final boolean isRegisterFcm = preferences.getBoolean("IS_REGISTER_FCM", false);
// FCM token Register when onTokenRefresh method call
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String fcmToken = SharedPrefManager.getInstance(MainActivity.this).getDeviceToken();
if(!isRegisterFcm) {
RegisterFcmTokenRequest request = new RegisterFcmTokenRequest();
request.setFcmtoken(fcmToken);
performRegisterFcmRequest(request);
}
}
};
// FCM token Register when new user Login
if(SharedPrefManager.getInstance(this).getDeviceToken() != null && !isRegisterFcm) {
String fcmToken = SharedPrefManager.getInstance(MainActivity.this).getDeviceToken();
RegisterFcmTokenRequest request = new RegisterFcmTokenRequest();
request.setFcmtoken(fcmToken);
performRegisterFcmRequest(request);
}
}
In the onDestroy method
unregisterReceiver(broadcastReceiver);
This class maintains the Shredpreferance for FCM token
public class SharedPrefManager {
private static final String SHARED_PREF_NAME = "FCMSharedPref";
private static final String TAG_TOKEN = "tagtoken";
private static SharedPrefManager mInstance;
private static Context mCtx;
private SharedPrefManager(Context context) {
mCtx = context;
}
public static synchronized SharedPrefManager getInstance(Context context) {
if (mInstance == null) {
mInstance = new SharedPrefManager(context);
}
return mInstance;
}
//this method will save the device token to shared preferences
public boolean saveDeviceToken(String token){
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(TAG_TOKEN, token);
editor.apply();
return true;
}
//this method will fetch the device token from shared preferences
public String getDeviceToken(){
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
return sharedPreferences.getString(TAG_TOKEN, null);
}
}
I want to retrieve my token and i'm doing exactly as many examples says
On FirebaseMessagingService i have this
#Override
public void onNewToken(String token) {
super.onNewToken(token);
Log.e("Refreshed token:",token);
}
And i got the error
Method does not override method from it's superclass
and of course the super.onNewToken(token) has the error
cannot resolve method
On my mainactivity i have this inside OnCreate()
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( MyActivity.this, new OnSuccessListener<InstanceIdResult>() {
#Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
}
});
And the errors i get are:
Cannot resolve getInstanceId()
Cannot resolve InstanceIdResult
cannot
resolve getToken()
and Method does not override method from it's
superclass
Update
Class declaration
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = MyFirebaseMessagingService.class.getSimpleName();
private NotificationUtils notificationUtils;
#Override
public void onNewToken(String token) {
super.onNewToken(token);
Log.e("Refreshed token:",token);
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.e(TAG, "From: " + remoteMessage.getFrom());
if (remoteMessage == null)
return;
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.e(TAG, "Notification Body: " + remoteMessage.getNotification().getBody());
handleNotification(remoteMessage.getNotification().getBody());
}
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
try {
JSONObject json = new JSONObject(remoteMessage.getData().toString());
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}
Dependencies
implementation 'com.google.firebase:firebase-core:16.0.5'
implementation 'com.google.firebase:firebase-messaging:17.3.4'
Update v2
public class FirebaseMessagingService extends com.google.firebase.iid.zzb {
private static final java.util.Queue<java.lang.String> zzoma;
public FirebaseMessagingService() { /* compiled code */ }
#android.support.annotation.WorkerThread
public void onMessageReceived(com.google.firebase.messaging.RemoteMessage remoteMessage) { /* compiled code */ }
#android.support.annotation.WorkerThread
public void onDeletedMessages() { /* compiled code */ }
#android.support.annotation.WorkerThread
public void onMessageSent(java.lang.String s) { /* compiled code */ }
#android.support.annotation.WorkerThread
public void onSendError(java.lang.String s, java.lang.Exception e) { /* compiled code */ }
#com.google.android.gms.common.internal.Hide
protected final android.content.Intent zzp(android.content.Intent intent) { /* compiled code */ }
#com.google.android.gms.common.internal.Hide
public final boolean zzq(android.content.Intent intent) { /* compiled code */ }
#com.google.android.gms.common.internal.Hide
public final void handleIntent(android.content.Intent intent) { /* compiled code */ }
static void zzr(android.os.Bundle bundle) { /* compiled code */ }
static boolean zzal(android.os.Bundle bundle) { /* compiled code */ }
build.gradle (app):
implementation 'com.google.firebase:firebase-core:16.0.5'
implementation 'com.google.firebase:firebase-messaging:17.3.4'
extend class:
package /*package name*/;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
public class MyFcmListenerService extends FirebaseMessagingService {
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is also called
* when the Instance ID token is initially generated, so this is where
* you retrieve the token.
*/
#Override
public void onNewToken(String token) {
Log.d("TAG", "New token: " + token);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(token); //As I understand it, you need to implement it yourself.
}
}
in tag in AndroidManifest.xml:
<service
android:name=".MyFcmListenerService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Add to your activity where you want to get a token:
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(MainActivity.this, new OnSuccessListener<InstanceIdResult>() {
#Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
}
});
I want to send data (String) from service to Activity.
How can I do that?
this is my service and I want to send the token to RegisterActivity, but it doesn't work
public class FirebaseInstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
String token = FirebaseInstanceId.getInstance().getToken();
Log.d("My firebase id", "Refreshed token: " + token);
Intent intent = new Intent(getApplicationContext(), RegisterActivity.class);
intent.putExtra("TokenValue", token);
FirebaseInstanceIDService.this.startActivity(intent );
}
In RegisterActivity
Intent intent = getIntent();
String tokenValue = intent.getStringExtra("TokenValue");
Toast.makeText(RegisterActivity.this,tokenValue,Toast.LENGTH_SHORT).show();
Add flag FLAG_ACTIVITY_NEW_TASK in your intent before calling startActivity.
Intent intent = new Intent(getApplicationContext(), RegisterActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("TokenValue", token);
startActivity(intent);
using interface it can be done easily.first create a interface and then subscribe to this interface from activity or fragment from where you want to get the text.and then broadcast data from service
Try this:
This is my service class like this:
public class TokenService extends FirebaseInstanceIdService {
private static final String TAG = "FirebaseIDService";
public static String DeviceToc = "";
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.e(TAG, "Refreshed token: " + refreshedToken);
DeviceToc = refreshedToken;
Log.e("DeviceToc",""+refreshedToken);
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token) {
// Utils.storeUserPreferences(this, DeviceToc,token);
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0);
SharedPreferences.Editor editor = pref.edit();
editor.putString("deviceToc",token); // Storing string
editor.apply();
Log.i("token",""+token);
// Add custom implementation, as needed.
}
And this is my login activity get token using Shared preference like this
#Override
protected Map<String, String> getParams()
{
Context c=LoginActivity.this;
SharedPreferences pref = c.getApplicationContext().getSharedPreferences("MyPref", 0);
String device_tok = pref.getString("deviceToc", null);
//Pass the parameters to according to the API.
Map<String, String> params = new HashMap<String, String>();
params.put("user_name", emailedit.getText().toString().trim());
params.put("userDeviceToken",device_tok);
params.put("deviceType","android");
params.put("user_login_password", passwordedit.getText().toString().trim());
Log.d("params",""+params);
it helps you.
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! :)