我在我的安卓模拟器上看不到我的 ParsePush 通知

Posted

技术标签:

【中文标题】我在我的安卓模拟器上看不到我的 ParsePush 通知【英文标题】:I can't see my ParsePush Notification on my android emulator 【发布时间】:2021-10-12 23:29:08 【问题描述】:

我目前正在开发一个聊天应用程序,我想实现 Parse Server Push 通知。我遵循文档并放置所需的所有代码。我的问题是我看不到通知,即使控制台告诉我它已发送。

这是我的 MainActivity.java,Parse 安装在哪里。

@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("----------------------");
                
            
        );
    

这些是我在 graddle 模块上的实现。 (还有一个是连接到 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 模拟器中从来没有收到通知。我检查了我的解析仪表板,即使它说通知已发送,它也显示 0 次交付。我需要你的帮助,因为我不知道自己做错了什么。

如果需要,我的安卓模拟器信息如下: My android emulator info

[编辑 1] (我不知道如何引用要求我这样做的评论,但无论如何)因为我知道你可能需要安装类。 installation class 由于我卸载并再次安装了该应用程序,所有安装都来自模拟器。我的智能手机有算法,那是华为(我也看不到通知,但我知道这是由于华为与谷歌服务的问题)。

[编辑 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

"结果":true[

另外作为附加信息,当我尝试仅使用 FCM 进行推送时(也就是说,请遵循此 Firebase FCM documentation)并且结果基本相同,它说它已成功发送,但我在android 模拟器,甚至在我的旧智能手机(诺基亚 6)中也没有。

[编辑 4] 我打开了详细信息,这是我在解析日志中发现的关于 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    

【问题讨论】:

您介意分享您在安装课上看到的内容吗? 你是指得到 ParseInstallation.getCurrentInstallation() 的类吗? 最好在您的仪表板上查看。 您好,我将 Parse Dashboard 安装的图像放在 EDIT 1 上 SendPush2 将不起作用,因为您无法使用用户 ID 查询安装类。 SendPush3 将不起作用,因为您的 Installation 类上没有 user 指针。 SendPush 应该可以工作。您在使用时在日志、云代码响应和推送状态中看到了什么? 【参考方案1】:

要为 Android 设备发送推送通知,必填字段为 deviceTokenGCMSenderID

但是,根据你发的截图,你安装的GCMSenderId是空的,是发送推送通知所必需的。

在您的MainActivity 中,您没有明确设置它,这是正确保存它所必需的。

这是一个示例代码,展示了如何做到这一点:

 ParseInstallation installation = ParseInstallation.getCurrentInstallation();
    installation.put("GCMSenderId", INSERT_YOUR_SENDER_ID);
    installation.saveInBackground();

填写两个字段后,推送通知可能会正常工作。

【讨论】:

我使用了这个代码,它在字段上注册了发件人 ID。但是,仍然没有出现。 仪表板的结果是什么?您是否在服务器端设置了 FCM 凭据? 它说我用来发送通知的 Parse Cloud 函数的结果是未定义的。是的,我将 FCM api 密钥放在服务器上。我开始认为我在项目中放置的一些 php 代码可能存在问题。

以上是关于我在我的安卓模拟器上看不到我的 ParsePush 通知的主要内容,如果未能解决你的问题,请参考以下文章

如何仅在 android 应用程序中调用 ParsePush.SubscribeInBackground 方法一次?

为啥我的应用没有在安卓模拟器上运行?

我可以将安卓模拟器连接到我的网络吗?

Android:DataInputStream 和 DataOutputstream 看不到我的目录

我在 Bot builder 模拟器上看不到我的自适应卡,它显示为空白

在我的开发环境中找不到 Plist 文件