2016-07-09 2 views
1

Сегодня я хотел переключиться с GCM на FCM, поэтому я настроил все необходимое и хотел реализовать код на стороне сервера. Я использовал библиотеку gcm4j и изменил ее так, чтобы адрес переместился на https://fcm.googleapis.com/fcm/send.Авторизация FCM всегда сбой

Так им, выполнив следующие действия:

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 не равно нулю на самом деле , он правильно установлен с помощью моего ключа API FCM. Только реализация HTTPUrlConnection возвращает null, если кто-то пытается получить доступ к ключу Authorization.

Как вы можете видеть, я не могу соединиться с FCM. Код 401 означает, что аутентификация не удалась.

В чем проблема?

ответ

4

Убедитесь, что вы используете API-ключ server type, а не API-Ключ client или browser.

Если вы используете Firebase вы можете найти API-KEY в
Настройки проекта> Cloud Messaging

Если вы используете облако консоли, или вы не уверены, какой ключ вы используете, вас может сгенерировать новый ключ через через https://console.cloud.google.com

Цитирование в документации по
https://firebase.google.com/docs/cloud-messaging/concept-options#credentials

Ключ сервера: Ключ сервера, который авторизует ваш сервер приложений для доступа к Службам Google, включая отправку сообщений через Firebase Cloud Сообщения. [...]
Важно: Не указывайте ключ сервера в любом месте вашего клиентского кода. Кроме того, убедитесь, что для авторизации вашего сервера приложений используются только ключи сервера. Андроид, iOS и ключи браузера отклоняются FCM.

+0

Hello. Спасибо за ваш ответ. Это ключ сервера. По крайней мере, это название ключа в разделе «Настройки проекта»> «Облачные сообщения». Так он должен работать, не так ли? Нужен ли мне идентификатор отправителя? Я предполагаю, что не потому, что 'getToken()' в реализации android не принимает никаких параметров. – Mulgard

+0

есть. должно. вы можете попытаться повторно создать его для доступа к проекту с https://console.cloud.google.com> api> credentials. Но на данный момент это может быть проблемой в вашей библиотеке. –

+0

Ох. Консоль Firebase сообщает мне, что у меня есть ключ сервера. Облачная консоль, которую вы опубликовали, на самом деле говорит мне, что это андроид-ключ oO. – Mulgard

Смежные вопросы