FCM授权总是失败

时间:2016-07-09 17:04:41

标签: google-cloud-messaging firebase-cloud-messaging

今天我想从GCM切换到FCM,所以我设置了所需的一切,并希望实现服务器端代码。我使用了gcm4j库并对其进行了更改,以便地址转到https://fcm.googleapis.com/fcm/send

所以我正在做以下事情:

FCM fcm = new FCMDefault(new FCMConfig().withKey(FCMGlobals.FCM_API_KEY));

FCMRequest request = new FCMRequest().withRegistrationId(android.getRegistration())
    // .withCollapseKey(collapseKey)
    .withDelayWhileIdle(true)
    .withDataItem(FCMGlobals.FCM_PARAM_CODE, code)
    .withDataItem(FCMGlobals.FCM_PARAM_USER_ID, "" + user.getId())
    .withDataItem(FCMGlobals.FCM_PARAM_ADDITION, "" + addition);

ListenableFuture<FCMResponse> responseFuture = fcm.send(request);

Futures.addCallback(responseFuture, new FutureCallback<FCMResponse>() {

    public void onFailure(Throwable t) {
        log.error(t);
    }

    @Override
    public void onSuccess(FCMResponse response) {
        log.info(response.toString());
    }
});

该实施是:

protected FCMResponse executeRequest(FCMRequest request) throws IOException {
    byte[] content = this.objectMapper.writeValueAsBytes(request);

    HttpURLConnection conn = this.connectionFactory.open(this.fcmUrl);
    conn.setRequestMethod("POST");
    conn.addRequestProperty("Authorization", getAuthorization(request));
    conn.addRequestProperty("Content-Type", "application/json");
    conn.setDoOutput(true);
    conn.setFixedLengthStreamingMode(content.length);

    LoggerFactory.getLogger("FCMDefaultAbstract").info("Authorization: " + conn.getRequestProperty("Authorization"));
    LoggerFactory.getLogger("FCMDefaultAbstract").info("Content-Type: " + conn.getRequestProperty("Content-Type"));
    LoggerFactory.getLogger("FCMDefaultAbstract").info("send: " + new String(content));

    try (OutputStream outputStream = conn.getOutputStream()) {
        IOUtils.write(content, outputStream);
    } catch (Exception e) {
        throw new FCMNetworkException("Error sending HTTP request to FCM", e);
    }

    FCMResponse response;

    try (InputStream inputStream = conn.getInputStream()) {
        response = this.objectMapper.readValue(IOUtils.toByteArray(inputStream), FCMResponse.class);
    } catch (IOException e) {
        try (InputStream inputStreamError = conn.getErrorStream()) {
            String str = inputStreamError != null ? IOUtils.toString(inputStreamError) : "No error details provided";
            int responseCode = conn.getResponseCode();

            if (responseCode < 500) {
                throw new FCMNetworkException(conn.getResponseCode(), str.trim(), e);
            } else {
                throw new FCMNetworkException(conn.getResponseCode(), str.trim(), checkForRetryInResponse(conn), e);
            }
        }
    }

    response.setRequest(request);
    response.setRetryAfter(checkForRetryInResponse(conn));

    Iterator<String> iteratorId = request.getRegistrationIds().iterator();
    Iterator<FCMResult> iteratorResponse = response.getResults().iterator();

    while (iteratorId.hasNext() && iteratorResponse.hasNext()) {
        iteratorResponse.next().setRequestedRegistrationId(iteratorId.next());
    }

    if (iteratorId.hasNext()) {
        LOG.warn("Protocol error: Less results than requested registation IDs");
    }

    if (iteratorResponse.hasNext()) {
        LOG.warn("Protocol error: More results than requested registation IDs");
    }

    return response;
}

这里是日志输出:

FCMDefaultAbstract                      Authorization: null
FCMDefaultAbstract                      Content-Type:application/json
FCMDefaultAbstract                      send: {"registration_ids":["dMpvzp*************************************2lRsSl_5lFET2"],"data":{"CODE":"201","USER_ID":"1","ADDITION":"1468083549493"},"delay_while_idle":true}
FCM                                     FCMNetworkException: HTTP 401: No error details provided

Authorization标头实际上不为空。它是使用我的FCM API密钥正确设置的。如果有人试图访问HTTPUrlConnection密钥,则只有Authorization实现返回null。

如您所见,我无法与FCM连接。代码401表示身份验证失败。

这可能是什么问题?

1 个答案:

答案 0 :(得分:4)

检查您使用的是server type API-KEY,而不是clientbrowser API-KEY。

如果您使用的是Firebase,可以在中找到API-KEY 项目设置&gt;云消息传递

如果您使用的是云控制台,或者您不确定使用的是哪个密钥, 您可以通过https://console.cloud.google.com

生成新密钥

引用文档
https://firebase.google.com/docs/cloud-messaging/concept-options#credentials

  

服务器密钥:授权您的应用服务器访问的服务器密钥   Google服务,包括通过Firebase Cloud发送邮件   消息。 [...]
  重要提示:请勿在客户端代码中的任何位置包含服务器密钥。   此外,请确保仅使用服务器密钥来授权您的应用服务器。   FCM拒绝Android,iOS和浏览器密钥。