这是我的舱单:

<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]

当前回答

2023年1月 对于那些实现了最新的Firebase云消息(FCM)的应用程序,您可能不会被限制在后台或完全关闭的情况下分别为应用程序发送数据和通知以处理数据。正如这里的一些回答所解释的那样,简短的版本是:

在你的启动器活动上,监视启动时的额外内容; 测试您的FCM数据中的唯一键是否在列表中; 如果存在,获取必要的数据并调用您的活动来处理您想要做的处理。

//Firebase
// [START handle_data_extras]
if (getIntent().getExtras() != null) {
    boolean fcmExtraFlag = false;
    for (String key : getIntent().getExtras().keySet()) {
        Object value = getIntent().getExtras().get(key);
        Log.d(TAG, "Key: " + key + " Value: " + value);
        if(key.equalsIgnoreCase("tracerId")){
            //test your known key to be sure it is from fcm
            //this must have come from notification (system) tray
            //this will come whether the app was in the background or completely off
            //generally, this could be in the main activity as it has the intent-filter already set
            fcmExtraFlag = true;
        }
    }
    //pick fcm values if present and notify and/or process accordingly
    //you may add time-lookup to ignore delayed (time-passed) ones; and ignore
    if(fcmExtraFlag){
        String tracerId = (String) getIntent().getExtras().get("tracerId"); 
        //prepare your data as needed
        String tracerData = tracerId+">"+data-one+">"+data-two;
        String msgBody = "This is a test notification; data received: "+tracerId;
        String fcmMessage = msgBody;
        //start your confirmation activity, directly or whichever way
        SidUtils.firebaseStartConfirms(msgBody, tracerData, this);
    }
}
// [END handle_data_extras]

如前所述,如果可能的话,这应该在你的主活动中,以处理你的应用程序实际上关闭的情况-而不仅仅是在后台。这些将通过点击系统托盘上的应用程序通知来触发。

其他回答

像这样简单的总结

如果你的应用正在运行; 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());

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

快乐编码=)

要使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
    */
}

你要工作onmessagerreceived (RemoteMessage RemoteMessage)在后台只发送数据部分通知部分这:

"data":    "image": "",    "message": "Firebase Push Message Using API", 

"AnotherActivity": "True", "to": "设备id或设备令牌"

通过这个onMessageRecivied是调用后台和前台不需要处理通知使用通知托盘在你的启动器活动。 处理数据负载使用这个:

  public void onMessageReceived(RemoteMessage remoteMessage)
    if (remoteMessage.getData().size() > 0) 
    Log.d(TAG, "Message data payload: " + remoteMessage.getData());      

根据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函数处理。

此情况仅用于firebase管理通知 如果应用程序在后台,则不会触发FirebaseMessagingService

要处理这种情况,请转到launcher activity,检查附加的intent bundle,并使用以下代码打印出所有数据:

 intent?.extras?.let {it->
        for (key in bundle.keySet()) {
            val value = bundle[key]
            Log.d("NotificationData", String.format("%s %s (%s)", key, value.toString(), value!!.javaClass.name))
        }
    }

显示所有数据类型的签入日志;

例子:

我想从通知中获得周和标题将使用这段代码

intent?.extras?.let {it->
        if (it.containsKey("week")){
            
        }
        if (it.containsKey("title")){

        }