我想出了这些场景,
当应用程序进入时 前景 , 的 onMessageReceived() 强> 方法是从 的 FirebaseService 强> 。所以 的PendingIntent 将调用在服务类中定义的。
当应用程序进入时 背景 , 的 第一次活动 强> 叫做。
现在,如果你使用了 的 飞溅活动 强> , 然后 必须 请记住 的 splashactivity 强> 将被调用,否则如果没有splashActivity,那么无论第一个活动是什么,都将被调用。
然后你需要检查 的 getIntent() 强> 的 的 firstActivity 强> 看看它有没有 的 束 强> 。如果一切正常,你会看到捆绑在那里填充了值。如果值为 数据标签 从服务器发送看起来像这样,
"data": { "user_name": "arefin sajib", "value": "user name notification" }
然后在第一个活动中,你会看到, 有一个有效的意图( getIntent()不为null ),有效的bundle和inside bundle,将会提到上面提到的整个JSON 的 数据 强> 如 的 键 强> 。
对于这种情况,提取值的代码将如下所示,
if(getIntent()!=null){ Bundle bundle = getIntent().getExtras(); if (bundle != null) { try { JSONObject object = new JSONObject(bundle.getStringExtra("data")); String user_name = object.optString("user_name"); } catch (JSONException e) { e.printStackTrace(); } } }
这里有关于firebase消息的更清晰的概念。我是从他们的支持团队那里找到的。
的 Firebase有三种消息类型 强> :
的 通知消息 强> :通知消息适用于背景或前景。当应用程序处于后台时,通知消息将传递到系统托盘。如果应用程序位于前台,则会处理消息 onMessageReceived() 要么 didReceiveRemoteNotification 回调。这些基本上就是所谓的显示消息。
onMessageReceived()
didReceiveRemoteNotification
的 数据消息 强> :在Android平台上,数据信息可以在后台和前台工作。数据消息将由onMessageReceived()处理。这里的平台特定说明如下:在Android上,可以在用于启动活动的Intent中检索数据有效负载。详细说明,如果你有 "click_action":"launch_Activity_1" ,你可以通过检索这个意图 getIntent() 仅来自 Activity_1 。
"click_action":"launch_Activity_1"
getIntent()
Activity_1
的 包含通知和数据有效负载的消息 强> :在后台,应用程序在通知托盘中接收通知有效负载,并仅在用户点击通知时处理数据有效负载。在前台时,您的应用会收到一个消息对象,其中包含两个可用的有效负载。其次, click_action 参数通常用于通知有效负载而不是数据负载。如果在数据有效内容中使用,则此参数将被视为自定义键值对,因此您需要实现自定义逻辑才能使其按预期工作。
click_action
另外,我建议你使用 onMessageReceived 方法(请参阅数据消息)以提取数据包。根据您的逻辑,我检查了bundle对象,但没有找到预期的数据内容。以下是对可能提供更清晰的类似案例的引用。
onMessageReceived
有关更多信息,请访问我的 这个帖子
的 根据OAUTH 2.0更新了答案: 强>
的 接受的答案不再有效(错误401).. 强> 对于这种情况,现在使用OAUTH 2将会出现Auth问题
所以我阅读了firebase文档并根据文档发布数据消息的新方法是;
POST: https://fcm.googleapis.com/v1/projects/YOUR_FIREBASEDB_ID/messages:send
头
Key: Content-Type, Value: application/json
验证
Bearer YOUR_TOKEN
示例正文
{ "message":{ "topic" : "xxx", "data" : { "body" : "This is a Firebase Cloud Messaging Topic Message!", "title" : "FCM Message" } } }
在url中有Database Id,您可以在firebase控制台上找到它。 (去项目安排)
现在让我们拿走我们的令牌(它只有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); }); }); }
现在我可以在我的帖子请求中使用此标记。然后我发布我的数据消息,它现在由我的应用程序onMessageReceived函数处理。
像这样简单的总结
如果您的应用正在运行;
是触发器。
如果你的应用没有运行(通过刷卡杀死);
并非由direclty触发和交付。如果你有任何特定的键值对。他们不工作因为onMessageReceived()无效。
我已经找到了这种方式;
在你的启动器活动中,把这个逻辑,
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());
使用这行代码,我关闭了我的应用程序并打开了Google Play Market
快乐的编码=)
的 删除通知有效负载 强> 完全来自您的服务器请求。发送 的 只有数据 强> 并处理它 onMessageReceived() ,否则你的 onMessageReceived 当应用程序处于后台或被杀时,将不会触发。
这是我从服务器发送的内容:
{ "data":{ "id": 1, "missedRequests": 5 "addAnyDataHere": 123 }, "to": "fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs......" }
所以你可以收到你的数据 onMessageReceived(RemoteMessage message) 像这样:(假设我必须得到id)
onMessageReceived(RemoteMessage message)
Object obj = message.getData().get("id"); if (obj != null) { int id = Integer.valueOf(obj.toString()); }
同样,您可以获取从服务器发送的任何数据 onMessageReceived() 。
除了以上答案, 如果您正在使用测试推送通知 的 FCM控制台 强> ,'数据'键和对象是 的 不 强> 添加到推送通知包。因此,当App处于后台或被杀时,您将不会收到详细的推送通知。
在这种情况下,您必须选择后端管理控制台来测试应用程序后台方案。
在这里,您将为推送包添加“数据”键。因此,详细推送将按预期显示。 希望这对少有帮助。
这是一个明确的答案 文档 关于这个:
即使应用程序处于后台和前台,发送消息的简便方法如下: - 要使用API发送消息,您可以使用名为AdvancedREST Client的工具,它是chrome扩展,并使用以下参数发送消息。
Rest客户端工具链接: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo
使用此网址: - https://fcm.googleapis.com/fcm/send 内容类型:应用程序/ JSON 授权:key =您的服务器密钥From或Authoization密钥(参见下面的参考资料)
{ "data": { "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg", "message": "Firebase Push Message Using API" "AnotherActivity": "True" }, "to" : "device id Or Device token" }
可以通过访问Google开发人员控制台并单击项目左侧菜单上的“凭据”按钮来获取授权密钥。在列出的API密钥中,服务器密钥将是您的授权密钥。
并且您需要将接收器的tokenID放在使用API发送的POST请求的 to 部分中。
使用此代码,您可以在后台/前台获取通知并执行操作:
//Data should come in this format from the notification { "to": "/xyz/Notifications", "data": { "key1": "title notification", "key2": "description notification" } }
应用内使用此代码:
@Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); String key1Data = remoteMessage.getData().get("key1"); // use key1Data to according to your need }
你想在后台工作onMessageReceived(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,“消息数据有效负载:”+ remoteMessage.getData());
我遇到了同样的问题并重新编译了firebase库,并阻止它在应用程序在后台时发送通知
*图书馆 https://github.com/erdalceylan/com-google-firebase-messaging
dependencies { compile 'com.google.firebase:firebase-core:11.2.0' compile 'com.github.erdalceylan:com-google-firebase-messaging:v1-11.2.0' }
*
@WorkerThread public void onMessageReceived(RemoteMessage var1) { //your app is in background or foreground all time calling }
希望有所帮助祝好运
2018年6月答案 -
您必须确保消息中的任何位置都没有“通知”关键字。只包含“数据”,应用程序将能够处理onMessageReceived中的消息,即使在后台或已杀死。
的 使用云功能: 强>
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 });
的 然后在您的onMessageReceived()中,在您的类中扩展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.