这是我的舱单:
<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]
下面是关于firebase消息的更清晰的概念。我从他们的支援组找到的。
Firebase有三种消息类型:
通知消息:通知消息工作在后台或前台。当app在后台时,通知消息被传递到系统托盘。如果应用程序在前台,消息由onmessagerreceived()或didReceiveRemoteNotification回调处理。这些实质上就是所谓的显示消息。
数据消息:在Android平台上,数据消息可以工作在后台和前台。数据消息将由onMessageReceived()处理。在Android上,数据有效载荷可以在用于启动你的活动的Intent中检索。具体来说,如果你有"click_action":"launch_Activity_1",你只能通过getIntent()从Activity_1中检索这个意图。
Messages with both notification and data payloads: When in the background, apps receive the notification payload in the notification tray, and only handle the data payload when the user taps on the notification. When in the foreground, your app receives a message object with both payloads available. Secondly, the click_action parameter is often used in notification payload and not in data payload. If used inside data payload, this parameter would be treated as custom key-value pair and therefore you would need to implement custom logic for it to work as intended.
另外,我建议您使用onMessageReceived方法(参见数据消息)来提取数据包。根据您的逻辑,我检查了bundle对象,并没有发现预期的数据内容。这里有一个类似案例的参考,可能会更清楚。
欲了解更多信息,请访问我的这个线程
根据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函数处理。
根据文件显示,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测试有效负载通知+数据。不要忘记在高级选项部分填写自定义数据字段
2018年6月答案:
你必须确保消息中没有“通知”关键字。只包括“data”,应用程序将能够处理onmessagerreceived中的消息,即使在后台或已杀死。
使用云功能:
const message = {
token: token_id, // obtain device token id by querying data in firebase
data: {
title: "my_custom_title",
body: "my_custom_body_message"
}
}
return admin.messaging().send(message).then(response => {
// handle response
});
然后在onmessagerreceived()中,在你的类中扩展com.google.firebase.messaging.FirebaseMessagingService:
if (data != null) {
Log.d(TAG, "data title is: " + data.get("title");
Log.d(TAG, "data body is: " + data.get("body");
}
// build notification using the body, title, and whatever else you want.