带有解析服务器推送通知的FCM不匹配enderid和客户端应用程序错误 [英] FCM with Parse Server Push Notifications mismatchsenderid and client app error

查看:112
本文介绍了带有解析服务器推送通知的FCM不匹配enderid和客户端应用程序错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经在GCM上尝试过此操作,但是我无法使其与Parse Server一起使用..因此,我接受了stackoverflow用户的建议,并在FCM上进行了尝试.

I used to try this with GCM but I couldn't get it to work with Parse Server .. So I took a stackoverflow users advice and gave it a try with FCM .

我的设备像这样从FCM获取注册ID:

My device gets the registration id from FCM like this :

04-15 17:01:29.773 I/parse.GcmRegistrar(30144): GCM registration successful. Registration Id: APA91bFoNUPYdsjN6O_CkPje-O0hXjNz9kvURZMex72xClyBr_5o6D0vYtI-F0iyAGgSYjpIEaJt2QQ2CXk2qpI11gPFUSUdzH-NxQRXSK3hPkuaiC_lciVV3E0fp6A_VZUoYJ8VxOIh

我尝试从Firebase控制台发送带有此ID的通知,并且该通知正常工作,我的事件被触发,一切正常.

I tried to send a notification from the firebase console with this ID and its working my event gets fired and its all good .

当我想使用ParseCloud函数向我的用户发送通知时,问题就开始了.当我在设备输出日志中搜索错误时,我发现了这个错误:

The problem starts when i want to use ParseCloud function to send notifications to my users. While I was searching the device output log for errors i found this one :

04-15 17:01:25.490 E/parse.GcmRegistrar(30144): Found com.parse.push.gcm_sender_id <meta-data> element with value "id:767075137222", but the value is missing the expected "id:" prefix

这很奇怪,因为我的清单包含gcm_sender_id加上前缀ID:这是我的清单

This one is weird cause my manifest includes the gcm_sender_id plus it includes the prefix id: Here is my manifest

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.INTERNET" />


<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-permission android:name="android.permission.VIBRATE" />

<uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<permission android:name="com.companyname.appname.permission.C2D_MESSAGE" android:protectionLevel="signature" />

<uses-permission android:name="com.companyname.appname.permission.C2D_MESSAGE" />

<application android:label="Fuse.Android" android:icon="@mipmap/ic_launcher">

    <service android:name="parse.ParsePushService" />

    <receiver android:name="parse.ParsePushBroadcastReceiver"

    android:permission="com.google.android.c2dm.permission.SEND">

        <intent-filter>


            <action android:name="com.google.android.c2dm.intent.RECEIVE" />

            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="com.companyname.appname" />

        </intent-filter>

    </receiver>
    <meta-data android:name="com.parse.push.gcm_sender_id"
                    android:value="id:767075137222"/>
</application>

我在网上搜索过,有人说,如果您使用的API密钥不正确,则会出现此问题.发件人ID ..我正在使用这些:

I searched online and people were saying that this problem comes when you're not using the right API KEY & Sender Id .. I'm using these :

接下来,我对Parse Server的索引如下:

Next my index for Parse Server looks like this :

    // Example express application adding the parse-server module to expose Parse
// compatible API routes.

var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var path = require('path');

var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;

if (!databaseUri) {
  console.log('DATABASE_URI not specified, falling back to localhost.');
}
var pushConfig = {};
if (process.env.GCM_SENDER_ID && process.env.GCM_API_KEY) {
   pushConfig['android'] = { 
   senderId: process.env.GCM_SENDER_ID || '',
   apiKey: process.env.GCM_API_KEY || ''};
}



var api = new ParseServer({
  databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
  appId: process.env.APP_ID || 'myAppId',
  masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
  serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse',  // Don't forget to change to https if needed
    push: pushConfig,
  liveQuery: {
    classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
  }

});
// 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 app = express();

// 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
var mountPath = process.env.PARSE_MOUNT || '/parse';
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'));
});

var port = process.env.PORT || 1337;
var 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);

我已经将GCM_SENDER_ID和GCM_API_KEY定义为Heroku托管Parse的配置变量.

I've defined the GCM_SENDER_ID and GCM_API_KEY to the config vars of the Heroku hosting Parse .

从客户端应用程序调用ParseCloud函数后,我在heroku日志中得到了它:

After i call the ParseCloud function from the client app i get this in the heroku logs :

    Apr 15 08:03:02 fuseparse app/web.1: } method=POST, url=/parse/push, host=fuseparse.herokuapp.com, connection=close, user-agent=node-XMLHttpRequest, Parse/js1.11.1 (NodeJS 9.11.1), accept=*/*, content-type=text/plain, x-request-id=ea046fd0-5fb7-46b7-9ceb-e6a0fd2ebad1, x-forwarded-for=54.81.77.161, x-forwarded-proto=https, x-forwarded-port=443, via=1.1 vegur, connect-time=0, x-request-start=1523804582292, total-route-time=0, content-length=270, installationId=e2dc9f85-3c2f-464e-beca-c8b9d2cba528, alert=The Giants scored! 
Apr 15 08:03:02 fuseparse app/web.1: verbose: RESPONSE from [POST] /parse/push: { 
Apr 15 08:03:02 fuseparse app/web.1:   "headers": { 
Apr 15 08:03:02 fuseparse app/web.1:     "X-Parse-Push-Status-Id": "upnMh1652U" 
Apr 15 08:03:02 fuseparse app/web.1:   }, 
Apr 15 08:03:02 fuseparse app/web.1:   "response": { 
Apr 15 08:03:02 fuseparse app/web.1:     "result": true 
Apr 15 08:03:02 fuseparse app/web.1:   } 
Apr 15 08:03:02 fuseparse app/web.1: } X-Parse-Push-Status-Id=upnMh1652U, result=true 
Apr 15 08:03:02 fuseparse app/web.1: #### PUSH OK 
Apr 15 08:03:02 fuseparse app/web.1: verbose: _PushStatus upnMh1652U: sending push to installations with 1 batches 
Apr 15 08:03:02 fuseparse app/web.1: verbose: Sending push to 1 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM sending to 1 device 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM GCM Response: { 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM     "multicast_id": 5516369214301735000, 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM     "success": 0, 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM     "failure": 1, 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM     "canonical_ids": 0, 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM     "results": [ 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM         { 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM             "error": "MismatchSenderId" 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM         } 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM     ] 
Apr 15 08:03:02 fuseparse app/web.1: node-pre-gyp verb parse-server-push-adapter GCM } 
Apr 15 08:03:02 fuseparse app/web.1: verbose: _PushStatus upnMh1652U: sent push! 0 success, 1 failures 
Apr 15 08:03:02 fuseparse app/web.1: verbose: _PushStatus upnMh1652U: needs cleanup devicesToRemove=[] 

我已经待了好几天了..有人可以告诉我我试图做的事情是否可能以及我可能在哪里做错了吗???

I've been at it for days .. Can somebody tell me if what im trying to do is possible and if it is possible where i might be doing this wrong ???

推荐答案

此错误有问题的人:

04-15 17:01:25.490 E/parse.GcmRegistrar(30144): Found com.parse.push.gcm_sender_id <meta-data> element with value "id:767075137222", but the value is missing the expected "id:" prefix

但已在androidmanifest中定义了gcm_sender_id,很可能安装了错误的sdk或parse.dll.我所做的是下载了parseplatform github中提供的开源SDK,并修改了GcmRegistrar.cs类,以使sender_id的返回值不为null:

but has defined the gcm_sender_id in the androidmanifest most likely has a faulty sdk or parse.dll installed . What i did is I downloaded the open source SDK which is available in the parseplatform github and modified the GcmRegistrar.cs class to not return null for the sender_id :

这花了我很长时间,但是对于有相同问题的任何人,请下载最新的.dll,否则,如果问题仍然存在,则意味着该dll未更新,您必须手动执行此操作.以我为例,我使用的是.NET SDK,但尚未更新.

This took me a long time but for anyone who has the same problem pls download the latest .dll or if the problem still persists it means that the dll was not updated and you have to manually do this . In my case i was using the .NET Sdk and it wasn't updated .

下载开源sdk并将其替换为Internal/Push/GcmRegistrar.cs

Download the open source sdk and replace Internal/Push/GcmRegistrar.cs with this

using System;
using Android.App;
using Android.Content;
using Android.OS;
using System.Threading.Tasks;

namespace Parse {
  internal class GcmRegistrar {
    private const string LogTag = "parse.GcmRegistrar";

    private const string ExtraRegistrationId = "registration_id";

    private const string ExtraSenderId = "com.parse.push.gcm_sender_id";
    private const string ParseGcmSenderId = "1076345567071";

    public const string IntentRegisterAction = "com.google.android.c2dm.intent.REGISTER";

    private readonly Object mutex = new Object();
    private Request request;
    private Context context;

    public static GcmRegistrar GetInstance() {
      return Singleton.Instance;
    }

    private static class Singleton {
      public static readonly GcmRegistrar Instance = new GcmRegistrar(Application.Context);
    }

    private GcmRegistrar(Context context) {
      this.context = context;
    }

    private string getActualSenderIdFromExtra(Object senderIdExtra) {
            if (senderIdExtra == null ) {
        return null;
      }
      string senderId = senderIdExtra.ToString();
      if (!senderId.StartsWith("id:")) {
        return null;
      }

      return senderId.Substring(3);
    }

    public void Register() {
      ParseInstallation installation = ParseInstallation.CurrentInstallation;

      lock (mutex) {
        if (installation.DeviceToken == null && request == null) {
          var metadata = ManifestInfo.GetApplicationMetaData();
          object senderIdExtra = null;
          if (metadata != null) {
            senderIdExtra = metadata.Get(ExtraSenderId);
          }

          string senderIds = ParseGcmSenderId;
          if (senderIdExtra != null) {
            string senderId = getActualSenderIdFromExtra(senderIdExtra);

            if (senderId != null) {
              senderIds += "," + senderId;
            } else {
              Android.Util.Log.Error("parse.GcmRegistrar", "Found " + ExtraSenderId + " <meta-data> element with value \""
                + senderIdExtra.ToString() + "\", but the value is missing the expected \"id:\" prefix");
            }
          }
          request = Request.CreateAndSend(this.context, senderIds);
        }
      }
    }

    /// <summary>
    /// Handles GCM registration intent from <see cref="ParsePushBroadcastReceiver"/> and saves the GCM registration
    /// id as <see cref="ParseInstallation.CurrentInstallation"/> device token.
    /// </summary>
    /// <remarks>
    /// Should be called by a broadcast receiver or service to handle GCM registration response
    /// intent (com.google.android.c2dm.intent.REGISTRATION).
    /// </remarks>
    /// <param name="intent"></param>
    public Task HandleRegistrationIntentAsync(Intent intent) {
      if (intent.Action == ParsePushBroadcastReceiver.ActionGcmRegisterResponse) {
        string registrationId = intent.GetStringExtra(ExtraRegistrationId);

        if (registrationId != null && registrationId.Length > 0) {
          Android.Util.Log.Info(LogTag, "GCM registration successful. Registration Id: " + registrationId);
          ParseInstallation installation = ParseInstallation.CurrentInstallation;

          // Set `pushType` via internal `Set` method since we want to skip mutability check.
          installation.Set("pushType", "gcm");
          installation.DeviceToken = registrationId;

          return installation.SaveAsync();
        }
      }
      return Task.FromResult(0);
    }

    /// <summary>
    /// Encapsulates the GCM registration request-response, potentially using <c>AlarmManager</c> to
    /// schedule retries if the GCM service is not available.
    /// </summary>
    private class Request {
      private Context context;
      private string senderId;
      private PendingIntent appIntent;

      public static Request CreateAndSend(Context context, string senderId) {
        Request request = new Request(context, senderId);
        request.Send();

        return request;
      }

      private Request(Context context, string senderId) {
        this.context = context;
        this.senderId = senderId;
        appIntent = PendingIntent.GetBroadcast(context, 0, new Intent(), 0);
      }

      private void Send() {
        Intent intent = new Intent(IntentRegisterAction);
        intent.SetPackage("com.google.android.gsf");
        intent.PutExtra("sender", senderId);
        intent.PutExtra("app", appIntent);

        ComponentName name = null;
        try {
          name = context.StartService(intent);
        } catch (Exception) {
          // Do nothing.
        }
      }
    }
  }
}

这篇关于带有解析服务器推送通知的FCM不匹配enderid和客户端应用程序错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆