我目前正在开发一个聊天应用程序,我想实现解析服务器推送通知。我遵循文档并放入所需的所有代码。我的问题是,我看不到通知,即使控制台告诉我它已经发送了。
这是我的MainActivity.java,其中是解析安装。
@Override
protected void onCreate(Bundle savedInstanceState) {
notificationsPush();
createGraphicElements();
super.onCreate(savedInstanceState);
}
private void notificationsPush(){
ParseInstallation.getCurrentInstallation().saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
if (e == null){
System.out.println("---------------------");
System.out.println("SUCCESS ON INSTALLATION");
System.out.println("----------------------");
ParsePush.subscribeInBackground("Chat", new SaveCallback() {
@Override
public void done(ParseException e) {
if (e == null) {
System.out.println("----------------------");
System.out.println("SUCCESS ON CHANNEL");
System.out.println("----------------------");
} else {
System.out.println("----------------------");
System.out.println("ERROR ON CHANNEL: " + e.getMessage());
System.out.println("CODE: " + e.getCode());
System.out.println("----------------------");
}
}
});
}else{
System.out.println("---------------------");
System.out.println("ERROR ON INSTALLATION");
System.out.println("ERROR: " + e.getMessage());
System.out.println("CODE: " + e.getCode());
System.out.println("----------------------");
}
}
});
}
这些是我在gradle模块上的实现。(也有一个需要连接到Firebase)。
implementation platform('com.google.firebase:firebase-bom:28.4.1')
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-messaging'
//Parse Server
implementation "com.github.parse-community.Parse-SDK-Android:parse:1.26.0"
//PUSH Parse Server
implementation "com.github.parse-community.Parse-SDK-Android:fcm:1.26.0"
这些是我在ParseCloud上使用的函数(它们在main.js上)。
Parse.Cloud.define("SendPush", function(request) {
var query = new Parse.Query(Parse.Installation);
query.exists("deviceToken");
// here you can add other conditions e.g. to send a push to sepcific users or channel etc.
var payload = {
alert: request.params.Message
// you can add other stuff here...
};
Parse.Push.send({
data: payload,
where: query
}, {
useMasterKey: true
})
.then(function() {
response.success("Push Sent!");
}, function(error) {
response.error("Error while trying to send push " + error.message);
});
});
Parse.Cloud.define("SendPush2", function(request) {
var msg = request.params.Message;
var query = new Parse.Query(Parse.User);
var user = request.params.user;
query.equalTo("objectId", user);
Parse.Push.send({
where: query,
data:{
alert: {
"title" : msg,
"body" : msg
},
sound: 'default'
}
}, {
useMasterKey: true,
success: function(){
response.success("Push Sent!");
},
error: function(error){
response.error("Error while trying to send push " + error.message);
}
});
});
Parse.Cloud.define("SendPush3", function(request, response) {
var userId = request.params.user;
var message = "sening a test message"; //request.params.message;
var queryUser = new Parse.Query(Parse.User);
queryUser.equalTo('objectId', userId);
var query = new Parse.Query(Parse.Installation);
query.matchesQuery('user', queryUser);
Parse.Push.send({
where: query,
data: {
alert: message,
badge: 0,
sound: 'default'
}
}, {
success: function() {
console.log('##### PUSH OK');
response.success();
},
error: function(error) {
console.log('##### PUSH ERROR');
response.error('ERROR');
},
useMasterKey: true
});
});
最后,我在我的应用程序中测试那些ParseCloud函数来发送通知的代码。
private void sendMessage(){
if(messageEditText.getText().toString().length() > 0) {
String messageToSend = messageEditText.getText().toString();
messageEditText.setText("");
MessageBO messageBO = new MessageBO();
messageBO.setText(messageToSend);
messageBO.setUserIdSender(idUser);
messageBO.setUserIdReceiver(idContact);
insertMessage(messageBO.getUserIdSender().toString(),
messageBO.getUserIdReceiver().toString(),
messageBO.getText().toString());
enviarNotificacionPush(messageBO);
}
actualizarMensajes();
}
private void sendNotificationPush(MessageBO m){
HashMap<String,String> map = new HashMap<String, String>();
map.put("Message", m.getText().toString());
ParseCloud.callFunctionInBackground("SendPush",map, new FunctionCallback<Object>() {
@Override
public void done(Object object, ParseException e) {
if (e == null){
System.out.println("----------------------------");
System.out.println("NOTIFICATION SUCCES: " + object);
System.out.println("----------------------------");
}else{
System.out.println("----------------------------");
System.out.println("ERROR ON NOTIFICATION PUSH: " + e.getMessage());
System.out.println("CODE: " + e.getCode());
System.out.println("----------------------------");
}
}
});
HashMap<String,String> map2 = new HashMap<String, String>();
map2.put("Message", m.getText().toString());
map2.put("user", idUser);
ParseCloud.callFunctionInBackground("SendPush2",map2, new FunctionCallback<Object>() {
@Override
public void done(Object object, ParseException e) {
if (e == null){
System.out.println("----------------------------");
System.out.println("NOTIFICATION 2.0 SUCCESS: " + object);
System.out.println("----------------------------");
}else{
System.out.println("----------------------------");
System.out.println("ERROR ON NOTIFICATION PUSH 2.0: " + e.getMessage());
System.out.println("CODE: " + e.getCode());
System.out.println("----------------------------");
}
}
});
ParseCloud.callFunctionInBackground("SendPush3",map2, new FunctionCallback<Object>() {
@Override
public void done(Object object, ParseException e) {
if (e == null){
System.out.println("----------------------------");
System.out.println("NOTIFICACION 3.0 SUCCESS: " + object);
System.out.println("----------------------------");
}else{
System.out.println("----------------------------");
System.out.println("ERROR ON NOTIFICACION PUSH 3.0: " + e.getMessage());
System.out.println("CODE: " + e.getCode());
System.out.println("----------------------------");
}
}
});
}
正如你所看到的,我使用了3个发送通知的函数,它们都说这是成功的,但是在我的android模拟器中从来没有收到通知。我检查我的parse Dashboard,尽管它说通知已经发送,但它也说0交付。我需要你的帮助,因为我不知道我到底做错了什么。
如果你需要,我的Android模拟器的信息如下:My android emulator info
[编辑1](我不知道如何参考要求我这样做的评论,但无论如何)因为我看到你可能需要安装类。安装类由于我卸载并重新安装应用程序,所有安装都来自模拟器。我的智能手机有一个算法,那是华为的(我也看不到通知,但我知道这是由于华为与谷歌服务的问题)。
[EDIT 2]你好,这是我的解析服务器配置(也就是我的解析的index.js
)。顺便说一下,我正在使用parse_server_example
存储库。
// Example express application adding the parse-server module to expose Parse
// compatible API routes.
const express = require('express');
const ParseServer = require('parse-server').ParseServer;
const path = require('path');
var ParseDashboard = require('parse-dashboard');
const args = process.argv || [];
const test = args.some(arg => arg.includes('jasmine'));
const databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;
if (!databaseUri) {
console.log('DATABASE_URI not specified, falling back to localhost.');
}
const config = {
databaseURI: databaseUri || 'mongodb://admin:123@localhost:27017/ParseServer?authSource=admin',
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID || 'MY_APP_ID',
masterKey: process.env.MASTER_KEY || 'MY_MASTER_KEY', //Add your master key here. Keep it secret!
serverURL: process.env.SERVER_URL || 'http://192.168.10.100:1337/parse/', // Don't forget to change to https if needed
liveQuery: {
classNames: ['Posts', 'Comments'], // List of classes to support for query subscriptions
},
push: {
android: {
apiKey: 'AAAASP09btg:APA91bGxn3e0vJX0ri2DeFEWUjAODTCaP3mfCQ0la3oiIgNqNYUlj2THFlEwRjqnXGuI-8H_l5-0xZtyscn3yY4mRrAL5tNHYXrM8NBltgCwCx1gH8LFVvgAWubmV2Zsa5NkmD53vCeO'
}
}
};
// Client-keys like the javascript key or the .NET key are not necessary with parse-server
// If you wish you require them, you can set them as options in the initialization above:
// javascriptKey, restAPIKey, dotNetKey, clientKey
var configdashboard = {
"allowInsecureHTTP": true,
"apps": [
{
"serverURL": "http://192.168.10.100:1337/parse/",
"appId": "MY_APP_ID",
"masterKey": "MY_MASTER_KEY",
"appName": "ParseServer01"
}
],"users": [
{
"user": "root",
"pass": "123456"
}
]
};
var dashboard = new ParseDashboard(configdashboard,{allowInsecureHTTP:configdashboard.allowInsecureHTTP});
const app = express();
app.use('/dashboard', dashboard);
// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
// Serve the Parse API on the /parse URL prefix
const mountPath = process.env.PARSE_MOUNT || '/parse';
if (!test) {
const api = new ParseServer(config);
app.use(mountPath, api);
}
// Parse Server plays nicely with the rest of your web routes
app.get('/', function (req, res) {
res.status(200).send('I dream of being a website. Please star the parse-server repo on GitHub!');
});
// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function (req, res) {
res.sendFile(path.join(__dirname, '/public/test.html'));
});
const port = process.env.PORT || 1337;
if (!test) {
const httpServer = require('http').createServer(app);
httpServer.listen(port, function () {
console.log('parse-server-example running on port ' + port + '.');
});
// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpServer);
}
module.exports = {
app,
config,
};
[EDIT 3]你好,我试着用curl发送通知,结果是这样的:
curl -X POST
-H "X-Parse-Application-Id: wPacsFQMmP" -H "X-Parse-Master-Key: DwonoEbeNf" -H "Content-Type: application/json" -d '{ "where": { "deviceType": { "$in": [ "android" ] } }, "data": { "title": "The Shining", "alert": "All work and no play makes Jack a dull boy." } }' http://192.168.10.100:1337/parse/push
{"result"真}[
也作为额外的信息,当我尝试使用FCM推送时(这意味着,遵循这个Firebase FCM文档),结果基本上是相同的,它说它被成功发送,但我没有看到它在android模拟器上,甚至没有在我的旧智能手机(诺基亚6)。
[EDIT 4]我打开verbose,这是我在关于SendPush云功能的解析日志中发现的。
REQUEST for [POST] /parse/push: {\n \"channels\": [\n \"SignChat\"\n ],\n \"data\": {\n \"alert\": \"The Giants won against the Mets 2-3.\"\n }\n}",n "method": "POST",n "timestamp": "2021-10-28T20:25:27.623Z",n "url": "/parse/push"n },n {n "level": "verbose",n "message": "RESPONSE from [POST] /parse/functions/SendPush: {\n \"response\": {}\n}",n "result": {n "response": {}n },n "timestamp": "2021-10-28T20:25:27.619Z"n }
Android设备发送推送通知,必填字段为deviceToken
和GCMSenderID
。
然而,根据你发送的截图,你的安装的GCMSenderId是空的,它是发送推送通知所必需的。
在你的MainActivity
中,你没有显式地设置它,这是正确保存它所需要的。
下面的示例代码展示了如何做到这一点:
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
installation.put("GCMSenderId", INSERT_YOUR_SENDER_ID);
installation.saveInBackground();
一旦两个字段都被填满,推送通知可能会正常工作。