这是我的舱单:

<service android:name=".fcm.PshycoFirebaseMessagingServices">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

<service android:name=".fcm.PshycoFirebaseInstanceIDService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>

当应用程序在后台和通知到达,然后默认通知来,不运行我的onmessagerreceived代码。

这是我的onMessageReceived代码。如果我的应用程序在前台运行,而不是在后台运行,就会调用这个函数。我怎么能运行这段代码时,应用程序是在后台太?

// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // If the application is in the foreground handle both data and notification messages here.
    // 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.
    data = remoteMessage.getData();
    String title = remoteMessage.getNotification().getTitle();
    String message = remoteMessage.getNotification().getBody();
    String imageUrl = (String) data.get("image");
    String action = (String) data.get("action");
    Log.i(TAG, "onMessageReceived: title : "+title);
    Log.i(TAG, "onMessageReceived: message : "+message);
    Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
    Log.i(TAG, "onMessageReceived: action : "+action);

    if (imageUrl == null) {
        sendNotification(title,message,action);
    } else {
        new BigPictureNotification(this,title,message,imageUrl,action);
    }
}
// [END receive_message]

当前回答

根据文件显示,2017年5月17日

当你的应用在后台时,Android 将通知消息定向到系统托盘。用户轻按 通知默认打开应用程序启动器。 这包括同时包含通知和数据有效负载的消息 (以及从Notifications控制台发送的所有消息)。在这些 在情况下,通知被传递到设备的系统托盘,和 数据有效负载是在您的意图的附加部分中交付的 发射器的活动。

所以,你应该同时使用有效负载通知和数据:

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

不需要使用click_action。你应该从LAUNCHER活动中获得额外的意图

<activity android:name=".MainActivity">
        <intent-filter>
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>

Java代码应该在MainActivity的onCreate方法上:

Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
    Bundle extras = intent.getExtras();
    String someData= extras.getString("someData");
    String someData2 = extras.getString("someData2");
}

您可以从Firebase Notifications Console测试有效负载通知+数据。不要忘记在高级选项部分填写自定义数据字段

其他回答

要使firebase库在以下情况下调用onmessagerecreceived ()

应用程序在前台 后台应用程序 应用程序已被杀死

你不能把JSON键通知在你的请求到Firebase API,而是使用数据,见下文。

当你的应用程序处于后台或被杀死时,下面的消息将不会调用你的onmessagerreceived(),并且你不能自定义你的通知。

{
   "to": "/topics/journal",
   "notification": {
       "title" : "title",
       "text": "data!",
       "icon": "ic_notification"
    }
}

但是用这个方法就可以了

{
  "to": "/topics/dev_journal",
   "data": {
       "text":"text",
       "title":"",
       "line1":"Journal",
       "line2":"刊物"
   }
} 

基本上,消息是在参数RemoteMessage中与数据对象一起发送的,如Map<String, String>,然后您可以在这里的代码片段中管理onmessagerreceived中的通知

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();

     //you can get your text message here.
     String text= data.get("text");


     NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        // optional, this is to make beautiful icon
             .setLargeIcon(BitmapFactory.decodeResource(
                                    getResources(), R.mipmap.ic_launcher))  
        .setSmallIcon(smallIcon)  //mandatory
      .......
    /*You can read more on notification here:
    https://developer.android.com/training/notify-user/build-notification.html
    https://www.youtube.com/watch?v=-iog_fmm6mE
    */
}

根据OAUTH 2.0:

由于FCM现在使用OAUTH 2,在这种情况下将会有认证问题

所以我阅读了firebase文档,并根据文档发布数据消息的新方法是;

POST: https://fcm.googleapis.com/v1/projects/YOUR_FIREBASEDB_ID/messages:send

Key: Content-Type, Value: application/json

Auth

Bearer YOUR_TOKEN 

例子的身体

{
   "message":{
    "topic" : "xxx",
    "data" : {
         "body" : "This is a Firebase Cloud Messaging Topic Message!",
         "title" : "FCM Message"
          }
      }
 }

在url中有数据库Id,你可以在你的firebase控制台上找到它。(Go项目设置)

现在让我们用我们的代币(它只有效1小时):

首先在Firebase控制台中,打开设置>服务帐户。单击“生成新的私钥”,安全存储包含该私钥的JSON文件。我需要这个JSON文件来手动授权服务器请求。我下载了。

然后我创建了一个node.js项目,并使用这个函数来获得我的令牌;

var PROJECT_ID = 'YOUR_PROJECT_ID';
var HOST = 'fcm.googleapis.com';
var PATH = '/v1/projects/' + PROJECT_ID + '/messages:send';
var MESSAGING_SCOPE = 'https://www.googleapis.com/auth/firebase.messaging';
var SCOPES = [MESSAGING_SCOPE];

  router.get('/', function(req, res, next) {
      res.render('index', { title: 'Express' });
      getAccessToken().then(function(accessToken) {
        console.log("TOKEN: "+accessToken)
      })

    });

function getAccessToken() {
return new Promise(function(resolve, reject) {
    var key = require('./YOUR_DOWNLOADED_JSON_FILE.json');
    var jwtClient = new google.auth.JWT(
        key.client_email,
        null,
        key.private_key,
        SCOPES,
        null
    );
    jwtClient.authorize(function(err, tokens) {
        if (err) {
            reject(err);
            return;
        }
        resolve(tokens.access_token);
    });
});
}

现在我可以在我的post请求中使用这个令牌。然后我发布我的数据消息,它现在由我的应用程序onmessagerecreceived函数处理。

像这样简单的总结

如果你的应用正在运行; onMessageReceived ()

是触发器。

如果你的应用程序没有运行(通过滑动杀死); onMessageReceived ()

不是直接触发和传递的。如果你有特殊的键值对。它们不工作,因为onmessagerecreceived()不工作。

我找到了这条路;

在你的启动器活动中,放入这样的逻辑,

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState, R.layout.activity_splash);

    if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("PACKAGE_NAME")) {

        // do what you want

        // and this for killing app if we dont want to start
        android.os.Process.killProcess(android.os.Process.myPid());

    } else {

        //continue to app
    }
}

在这个if块中,根据firebase UI搜索你的密钥。

在这个例子中,我的键和值就像上面那样;(对不起,语言=))

当我的代码工作时,我得到“com.rda.note”。

android.os.Process.killProcess(android.os.Process.myPid());

有了这行代码,我关闭了我的应用程序,打开谷歌播放市场

快乐编码=)

要在后台捕获消息,您需要使用BroadcastReceiver

import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.legacy.content.WakefulBroadcastReceiver
import com.google.firebase.messaging.RemoteMessage

class FirebaseBroadcastReceiver : WakefulBroadcastReceiver() {

    val TAG: String = FirebaseBroadcastReceiver::class.java.simpleName

    override fun onReceive(context: Context, intent: Intent) {

        val dataBundle = intent.extras
        if (dataBundle != null)
            for (key in dataBundle.keySet()) {
                Log.d(TAG, "dataBundle: " + key + " : " + dataBundle.get(key))
            }
        val remoteMessage = RemoteMessage(dataBundle)
        }
    }

把这个加到你的舱单上

<receiver
      android:name="MY_PACKAGE_NAME.FirebaseBroadcastReceiver"
      android:exported="true"
      android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
</receiver>

因为从Firebase通知UI发送的显示消息只在应用程序处于前台时有效。对于数据消息,需要对FCM进行POST调用

步骤

安装高级休息客户端谷歌Chrome扩展 添加以下头文件 关键字:Content-Type,值:application/json 密钥:授权,值:Key ="您的服务器密钥" 添加正文 如果使用主题: { "to": "/topics/topic_name", "数据":{ "key1": "value1", "key2": "value2", } } 如果使用注册id: { "registration_ids": "[{"id"},{id1}]", "数据":{ "key1": "value1", "key2": "value2", } }


它!。现在像往常一样收听onmessagerreceived回调。

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String value1 = data.get("key1");
     String value2 = data.get("key2");
}