Firebase(FCM):在通知点击时打开活动并传递数据。安卓

11 浏览
0 Comments

Firebase(FCM):在通知点击时打开活动并传递数据。安卓

应该清楚如何处理Firebase通知和数据的实现。我阅读了很多答案,但似乎无法使其工作。以下是我的步骤:

1.) 我在PHP中将通知和数据传递给Android,看起来还不错:

$msg = array
    (
         "body" => $body,
         "title" => $title,
         "sound" => "mySound"
    );
    $data = array
    (
         "user_id" => $res_id,
         "date" => $date,
         "hal_id" => $hal_id,
         "M_view" => $M_view
    );
    $fields = array
    (
        'registration_ids' => $registrationIds,
        'notification' => $msg,
        'data' => $data
    );
    $headers = array
    (
        'Authorization: key='.API_ACCESS_KEY,
        'Content-Type: application/json'
    );
    $ch = curl_init();
    curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/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 );
    curl_close( $ch );

2.) 当通知和数据在Android中接收到时,会显示通知。当我点击该通知时,它会打开应用程序。但是我无法弄清楚在打开应用程序时如何处理数据。应用程序在前台和后台时有几个不同之处。我现在的代码如下:

public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    String user_id = "0";
    String date = "0";
    String cal_id = "0";
    String M_view = "0";
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        user_id = remoteMessage.getData().get("user_id");
        date = remoteMessage.getData().get("date");
        hal_id = remoteMessage.getData().get("hal_id");
        M_view = remoteMessage.getData().get("M_view");
    }
    //调用生成通知的方法
    sendNotification(remoteMessage.getNotification().getBody(), user_id, date, hal_id, M_view);
}
private void sendNotification(String messageBody, String user_id, String date, String hal_id, String M_view) {
    Intent intent = new Intent(this, MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra("fcm_notification", "Y");
    intent.putExtra("user_id", user_id);
    intent.putExtra("date", date);
    intent.putExtra("hal_id", hal_id);
    intent.putExtra("M_view", M_view);
    int uniqueInt = (int) (System.currentTimeMillis() & 0xff);
    PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), uniqueInt, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);
    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
    notificationBuilder.setSmallIcon(R.drawable.ic_launcher)
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);
    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(0, notificationBuilder.build());
}}

3.) 当我使用上述代码,并且当我点击通知时,它只是在后台打开应用程序。如果应用程序在前台,则在通知点击时它只是取消通知。然而,我希望在两种情况下(前台和后台)都能接收数据并打开特定的Activity。我在MainActivity中有以下代码,但我无法获取数据。fcm_notification、date、hal_id都返回null。

public class MainActivity extends Activity {
 UserFunctions userFunctions;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
    Intent intent_o = getIntent();
}
@Override
protected void onResume() {
    super.onResume();
    userFunctions = new UserFunctions();
    if(userFunctions.isUserLoggedIn(getApplicationContext())){
        Intent intent_o = getIntent();
        String fcm_notification = intent_o.getStringExtra("fcm_notification") ;
        String user_id = intent_o.getStringExtra("user_id");
        String date = intent_o.getStringExtra("date");
        String hal_id = intent_o.getStringExtra("hal_id");
        String M_view = intent_o.getStringExtra("M_view");
        Intent intent = new Intent(this, JobList.class);
        // THIS RETURNS NULL, user_id = null
        System.out.print("FCM" + user_id);
        startActivity(intent);
        finish();
    }else{
        // user is not logged in show login screen
        Intent login = new Intent(this, LoginActivity.class);
        startActivity(login);
        // Closing dashboard screen
        finish();
    }
}}

如果有人能指导或建议如何从Firebase的MainActivity.java中检索数据(无论是在前台还是后台),那将是太棒了。

0
0 Comments

问题原因:在使用Firebase Cloud Messaging (FCM)发送通知时,如果通知载荷(notification payload)存在,那么数据载荷(data payload)将不会传递给onMessageReceived()方法。

解决方法:移除FCM消息的通知载荷,以便将数据载荷传递给onMessageReceived()方法。当应用程序处于后台时,只有在没有通知载荷的情况下,数据载荷才会传递给onMessageReceived()方法。如果两个载荷都存在,则系统会自动处理通知部分(系统托盘),而您的应用程序会在启动器活动的意图的额外信息中获取数据载荷。

原始答案和更多信息请参考以下链接:

- [为什么会出现这种情况?如何处理推送通知?](https://stackoverflow.com/a/37845174/4836759)

- [kws的原始答案,请给他点赞。](https://stackoverflow.com/a/40311918/4836759)

0
0 Comments

问题的出现原因:通过查看视频以及参考其他答案和博客后,找到了解决方法。

解决方法:在MyFirebaseMessagingService类中的onMessageReceived方法中添加意图,然后在sendNotification方法中创建PendingIntent,并将意图作为参数传递。在NotificationReceive活动的onCreate或onResume方法中获取意图中的额外数据,并进行相应的操作。

解决方法中的代码如下:

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "MyFirebaseMsgService";
    public void onMessageReceived(RemoteMessage remoteMessage) {
        String user_id = "0";
        String date = "0";
        String hal_id = "0";
        String M_view = "0";
        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());
            user_id = remoteMessage.getData().get("user_id");
            date = remoteMessage.getData().get("date");
            hal_id = remoteMessage.getData().get("hal_id");
            M_view = remoteMessage.getData().get("M_view");
        }
        String click_action = remoteMessage.getNotification().getClickAction();
        //Calling method to generate notification
        sendNotification(remoteMessage.getNotification().getBody(), remoteMessage.getNotification().getTitle(), user_id, date, hal_id, M_view, click_action);
    }
    
    private void sendNotification(String messageBody, String messageTitle, String user_id, String date, String hal_id, String M_view, String click_action) {
        Intent intent = new Intent(click_action);
        intent.putExtra("user_id", user_id);
        intent.putExtra("date", date);
        intent.putExtra("hal_id", hal_id);
        intent.putExtra("M_view", M_view);
        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent,
                PendingIntent.FLAG_ONE_SHOT);
        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
        notificationBuilder.setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, notificationBuilder.build());
    }
}
// NotificationReceive活动中的代码
notification_Y_N = (TextView) findViewById(R.id.notification_Y_N);
user_id_text = (TextView) findViewById(R.id.user_id_text);
Intent intent_o = getIntent();
String user_id = intent_o.getStringExtra("user_id");
String date = intent_o.getStringExtra("date");
String hal_id = intent_o.getStringExtra("hal_id");
String M_view = intent_o.getStringExtra("M_view");
notification_Y_N.setText(date);
user_id_text.setText(hal_id);

需要注意的是,在Android Oreo中,NotificationCompat.Builder(this)已被弃用,请参考文档并使用Notification Channel实现。

对于在后台时指定活动的问题,请在发送通知时使用数据类型而不是通知类型,在服务器端发送通知时进行相应的设置。

以上是解决Firebase (FCM): open activity and pass data on notification click. android问题的原因和解决方法。

0
0 Comments

问题的出现原因:当应用程序位于前台时,可以在onMessageReceived()方法中处理推送的数据。但是当应用程序位于后台时,通知会被发送到Android系统托盘,并且可以从启动Activity的意图的附加信息中检索到数据负载。

解决方法:在启动的Activity中,通过检查意图的附加信息来获取通知的文本和标题,以及其他需要的数据。

以下是一个示例代码,可以在接收到通知后在启动Activity中获取通知的文本和标题:

if (getIntent().getExtras() != null) {
    for (String key : getIntent().getExtras().keySet()) {
        String value = getIntent().getExtras().getString(key);
        Log.d(TAG, "Key: " + key + " Value: " + value);
    }
}

另外,还可以将标题和正文作为数据属性发送,以便在启动Activity时作为附加信息读取它们。

0