The full method signature is...
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void)
What I want to be able to do is have the device respond when a push notification arrives. For example, the app might automatically navigate to a particular screen to show some data that's identified in the notification.
Android Equivalent Method is public void onMessageReceived(RemoteMessage remoteMessage)
#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());
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
scheduleJob();
} else {
// Handle message within 10 seconds
handleNow();
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
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.
}
For reference see 1 2
PackageManager.getLaunchIntentForPackage is what you're looking for.
This is how you'd use it :-
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(launchIntent);
Related
How can I start an alarm using background services when we receive notification ?
When my application is active then background service start easily, but when application is on background then background services can't run.
1. Why is this happening?
There are two types of messages in FCM (Firebase Cloud Messaging):
Display Messages: These messages trigger the onMessageReceived() callback only when your app is in foreground
Data Messages: Theses messages trigger the onMessageReceived() callback even if your app is in foreground/background/killed
override fun onMessageReceived(remoteMessage: RemoteMessage) {
// ...
// TODO(developer): Handle FCM messages here.
// Not getting messages here? See why this may be:
Log.d(TAG, "From: ${remoteMessage.from}")
// Check if message contains a data payload.
if (remoteMessage.data.isNotEmpty()) {
Log.d(TAG, "Message data payload: ${remoteMessage.data}")
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use WorkManager.
scheduleJob()
} else {
// Handle message within 10 seconds
handleNow()
}
}
// Check if message contains a notification payload.
remoteMessage.notification?.let {
Log.d(TAG, "Message Notification Body: ${it.body}")
}
// 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.
}
I am integrating firebase FCM push notifications on an android app and all things are working fine except when app goes background/killed, the MyFirebaseMessagingService is not called. It works fine when app is in foreground. The onMessageReceived() is not at all called when app is in background.
I want to send push notifications from Firebase console UI only to all subscribers at once, not trying to do 1-1 messaging or sending through web server.
Not that the service is not running when app is closed from Recent Apps tray, the app is not at all working when simply the app goes to background.
Below are the respective codes:
MyFirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
/**
* Called when message is received.
*
* #param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
// [START receive_message]
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO(developer): Handle FCM messages here.
// Not getting messages here? See why this may be:
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());
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
scheduleJob();
} else {
// Handle message within 10 seconds
handleNow();
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
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.
}
Service Declaration in Manifest
<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Application Class Declaration
FirebaseMessaging.getInstance().subscribeToTopic("weather")
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
String msg = "Subscribed";
if (!task.isSuccessful()) {
msg = "Message";
}
Log.d("Token", msg);
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
});
Update
onMessageReceived called in API 19 but not on 23 and 24.
Update
I am sending FCM notifications from a server, I can receive notifications but onMessageReceived is not called(foreground, background), even with data messages. This is the code I'm using.
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import uk.co.socktchat.socketchat.MainActivity;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
/**
* Called when message is received.
*
* #param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
// [START receive_message]
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// [START_EXCLUDE]
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
// [END_EXCLUDE]
// TODO(developer): Handle FCM messages here.
// Not getting messages here? See why this may be:
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());
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
scheduleJob();
} else {
// Handle message within 10 seconds
handleNow();
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
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.
}
// [END receive_message]
/**
* Schedule a job using FirebaseJobDispatcher.
*/
private void scheduleJob() {
// [START dispatch_job]
// [END dispatch_job]
}
/**
* Handle time allotted to BroadcastReceivers.
*/
private void handleNow() {
Log.d(TAG, "Short lived task is done.");
}
/**
* Create and show a simple notification containing the received FCM message.
*
* #param messageBody FCM message body received.
*/
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
}
}
My Manifest file
<service
android:name=".fcm.MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<!-- [END firebase_service] -->
<!-- [START firebase_iid_service] -->
<service
android:name=".fcm.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
json im posting from server
{
"data": {
"title": "5x1",
"body": "15:10"
},
"to" : "d6IJZlXAUZ4:APA91bF8kB_jBn_N93otIdRFsu89ZDhrFsL--i0I4TmS-LO_h3QQ79lu6VlTQe0poNpuUni7N45_jw2XMli",
"priority" : "high",
"content_available" : true
}
I don't see anything wrong, I tried different versions of Android, thinking android version could be any reason, but didn't seem the find any problem. Any ideas? Thank you.
Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.e(TAG, "Notification Payload: " + 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());
handleNotification(remoteMessage.getData());
}
As per FCM document
Notification messages contain a predefined set of user-visible keys.
Data messages, by contrast, contain only your user-defined custom
key-value pairs. Notification messages can contain an optional data
payload. Maximum payload for both message types is 4KB, except when
sending messages from the Firebase console, which enforces a 1024
character limit.
check that your message size is within limit.
In fact onMessageReceived is being called the whole time, it is just that Logcat didn't show any messages, weird enough it happened only with devices of API 19 above, on a device with API 19 Logcat is showing the messages, I can't explain why this happened but my problem was solved.
I am a little bit confusing on integrating FCM (Firebase cloud messaging) push notification on my application.
Normally, Rather than the Intent services other services are not stopped anymore in the middle. I have created my message receiving service by extending to the FirebaseMessagingService as follow
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#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, "NotificationBean Body: " + remoteMessage.getNotification().getBody());
//This method is responsible for handling notification
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());
}
}
}
}
and registered the service on manifest as follow:
<service android:name=".service.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
This service is run on when the app is live and running in the background too. But when the app is not in the background the service is not run anymore.
I have registered the service on Main Activity as follow
#Override
protected void onResume() {
super.onResume();
// register GCM registration complete receiver
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(Config.REGISTRATION_COMPLETE));
// register new push message receiver
// by doing this, the activity will be notified each time a new message arrives
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(Config.PUSH_NOTIFICATION));
// clear the notification area when the app is opened
NotificationUtils.clearNotifications(getApplicationContext());
}
#Override
protected void onPause() {
super.onPause();
}
Let me know anything wrong in my code. (Possibly not) .Why notifications are not running on background. How do I overcome this issue?
Thanks in advance.
use your server data or api like this
{
"to" : "deviceToken",
"notification" : {
"body" : "Pass body here",
"title" : "Title n",
"icon" : " icon ",
"sound" : "notification sound "
}
}
//for exa.
$fields=array('to'=>fdfdfdfdsfdsdfdfdsfdsfdfdsfd" ,'notification'=>array('title'=>'mytitle','body'=>$title,'click_action'=>'abc','icon'=>'ic_stat_final','sound'=>'default','color'=>'#00aff0'),'data'=>array('ghmid'=>$hgmid,'page'=>$page));
If your data is of type notification ie "Notification"then the onReceived method is not supposed to be get called when app is in background. Though it can be retrived when app comes to foreground. If it is of type data then it will get called.Change your type to "Data" instead of notification. Also when you change the data to type "Data" your getNotification() method may not work and app will get null pointer exception. Server data can also be of type where it has both "data" and "notification".
change json object key from notification to data
e.g
{
“to”: “device_ID/fcmID”,
“notification”: {
“body”: “great match!”,
“title”: “Portugal vs. Denmark”,
“icon”: “myicon”
}
}
change to
{
“to”: “device_ID/fcmID”,
“data”: {
“Nick”: “abc”,
“body”: “nfjwhhwruguig”,
“Room”: “cnrughwriugg”
},
}
Client app receives a data message in onMessageReceived() irrespective of the fact whether app is in foreground or background.
ref: https://blog.talentica.com/2017/01/20/firebase-cloud-messaging-in-android/
I am new to android Firebase and I want that when any new value is added to Firebase then I get any notification like your database is updated or so.. How can I do that..
Please help
You can do this by using Push Notification , During Registration, get the generated token and save it your database along with user details .
whenever a key/child is updated
fire up the Event to that tokenID
you should have a broadcast Receiver in you application which monitors the incoming firebase message
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
here is an Example https://github.com/firebase/friendlychat/blob/master/android/app/src/main/java/com/google/firebase/codelab/friendlychat/MyFirebaseMessagingService.java