在解析中为 Android 设置 DeviceToken

Posted

技术标签:

【中文标题】在解析中为 Android 设置 DeviceToken【英文标题】:set DeviceToken in parse for Android 【发布时间】:2016-06-13 21:46:42 【问题描述】:

我无法使用解析在安装表中设置设备令牌 我正在使用

ParseInstallation installation =ParseInstallation.getCurrentInstallation();
      installation.put("GCMSenderId",senderId);
      installation.put("pushType","gcm");
      installation.put("deviceToken",token);

但是当我尝试使用 save 时出现异常。

Cannot modify `deviceToken` property of an _Installation object. android

问题是,后端使用此 tokenId 为另一个提供商(OneSignal)发送推送通知,所以我想知道它是否可以在 deviceToken 行中写入(据我所知,这仅适用于 ios)。 我需要在 deviceToke 中写入我收到的 GCM 令牌。 谢谢

【问题讨论】:

如果您希望迁移到 OneSignal,您只需添加 GCMSenderId,因为在您进行此更改后,OneSignal 解析导入器将能够引入您现有的用户。 onesignal.com/blog/important-note-for-android-parse-push-users 如果 sdk 不允许,您可以尝试使用 currentUser 令牌的 rest api。 @jkasten 它能够带来我的用户,但没有更新更新 deviceToken,我无法获得成功发送的推送。 【参考方案1】:

我通过添加一个名为 setDeviceToken 的 Parse Cloud 函数解决了这个问题。这样我就可以使用MasterKey来修改安装记录了。

Parse.Cloud.define("setDeviceToken", function(request, response) 
    var installationId = request.params.installationId;
    var deviceToken = request.params.deviceToken;

    var query = new Parse.Query(Parse.Installation);
    query.get(installationId, useMasterKey: true).then(function(installation) 
        console.log(installation);
        installation.set("deviceToken", deviceToken);
        installation.save(null, useMasterKey: true).then(function() 
            response.success(true);
        , function(error) 
            response.error(error);
        )
    , function (error) 
        console.log(error);
    )
);

然后,在我的 Android 应用的Application.onCreate

OneSignal.idsAvailable(new OneSignal.IdsAvailableHandler() 
  @Override
  public void idsAvailable(String userId, String registrationId) 
      final ParseInstallation currentInstallation = ParseInstallation.getCurrentInstallation();

      if (registrationId != null) 
          HashMap<String, Object> params = new HashMap<>(2);
          params.put("installationId", currentInstallation.getObjectId());
          params.put("deviceToken", registrationId);

          ParseCloud.callFunctionInBackground("setDeviceToken", params, new FunctionCallback<Boolean>() 
              @Override
              public void done(java.lang.Boolean success, ParseException e) 
                  if (e != null) 
                      // logException(e);
                  
              
          );
      
  
);

【讨论】:

这是一个有用的解决方法,我确认正在使用 ParseServer v2.3.5 和 Android SDK v1.14.1。如果您使用的是 Firebase String registrationId = FirebaseInstanceId.getInstance().getToken(); 只是好奇,您为什么选择 onesignal 而不是 Firebase @jaynp? @JaimeAgudo OneSignal 轻松支持一系列高级功能,例如 A/B 测试、iOS 10 媒体附件、操作按钮。我现在没有全部使用它们,但有这个选项真是太好了!【参考方案2】:

对于未来的访问者,我使用 Parse Rest API 以不同的方式解决了这个问题:http://parseplatform.org/docs/rest/guide/

使用它,您可以绕过常规的 SDK 限制。只需向https://yourApp/parse/installtions/installationObjectIDHere 发出 put 请求。制作字典并将其编码为 JSON:

    Map<String, String> dictionary = new HashMap<String, String>();
    dictionary.put("deviceToken", yourToken);
    JSONObject jsonDictionary = new JSONObject(dictionary);
    String bodyAsString = jsonDictionary.toString();
    RequestBody body = RequestBody.create(JSON, bodyAsString);

然后发送请求,这应该可以工作。

【讨论】:

【参考方案3】:

joey 展示了正确的方法,我添加的额外部分是关于身份验证标头。 这就是我所做的:

    val JSON = MediaType.parse("application/json; charset=utf-8")

    val client = OkHttpClient()

    val installationObjectId = ParseInstallation.getCurrentInstallation().objectId

    val myAppId = getString(R.string.parse_app_id)

    val key = getString(R.string.parse_client_key)

    val server = getString(R.string.parse_server_url)

    val mRequestUrl = "$server/installations/$installationObjectId"

    val dictionary = HashMap<String, String?>()
    dictionary["deviceToken"] = myToken
    val jsonDictionary = JSONObject(dictionary)
    val bodyAsString = jsonDictionary.toString()

    val body = RequestBody.create(JSON, bodyAsString)

    val request = Request.Builder()
            .url(mRequestUrl)
            .put(body)
            .addHeader("X-Parse-Application-Id", myAppId)
            .addHeader("X-Parse-Client-Key", key)
            .build()

    client.newCall(request).execute()

【讨论】:

以上是关于在解析中为 Android 设置 DeviceToken的主要内容,如果未能解决你的问题,请参考以下文章

如何在 android 中为 TextView 设置字体? [复制]

如何在 Android 中为 SocketIO 设置传输?

如何在Android中为底部导航设置全宽

在 Android 中为 Activitiy.this 设置参数

如何在android中为jsoup设置用户代理和连接超时

如何在 Android Studio 中为颤振设置代码格式 [重复]