Firebase Cloud Messaging突然返回401

时间:2018-07-21 23:07:12

标签: java firebase firebase-cloud-messaging

我有一个非常困惑的问题。我正在设置一个管理应用,该应用将使用Firebase Cloud Messaging向目标客户端发送推送通知。它工作了一段时间,然后突然停止工作,我没有对代码进行任何更改-这是令人困惑的部分!

这是Firebase配置。

FirebaseConfiguration.java

@Configuration
public class FirebaseConfig {

    private final String databaseUrl;

    private final String configPath;

    @Inject
    public FirebaseConfig(
            @Value("${firebase.database.url}") String databaseUrl, 
            @Value("${firebase.config.path}") String configPath) {
        this.databaseUrl = databaseUrl;
        this.configPath = configPath;
    }

    @Bean
    public DatabaseReference firebaseDatabase() {
        return FirebaseDatabase.getInstance().getReference();
    }

    @PostConstruct
    public void init() throws IOException {
        /*
         * https://firebase.google.com/docs/admin/setup Create service account; Download .json config file
         */
        final InputStream serviceAccount = FirebaseConfig.class.getClassLoader().getResourceAsStream(configPath);

        final FirebaseOptions options = new FirebaseOptions.Builder()
                .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                .setDatabaseUrl(databaseUrl)
                .build();

        FirebaseApp.initializeApp(options);
    }
}

在这里,configPath.json文件的路径,其中包含我的Firebase应用程序的所有配置,该配置是在应用程序的Firebase控制台中生成的。

myapp-firebase-config.json

{
  "type": "service_account",
  "project_id": "myapp",
  "private_key_id": "8564e07po7cff976068c702dcdpodbbb0cu3e6",
  "private_key": "-----BEGIN PRIVATE KEY-----...\n-----END PRIVATE KEY-----\n",
  "client_email": "firebase-adminsdk-jo9yp@myapp.iam.gserviceaccount.com",
  "client_id": "12345",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-jo9yp%myapp.iam.gserviceaccount.com"
}

现在,尝试发送推送通知但失败的代码。

Message message = Message.builder()
                .putData("Message", "Test 123")
                .setToken(token)
                .build();

        ApiFuture<String> response = FirebaseMessaging.getInstance().sendAsync(message);
        final String result = response.get(); // throws the exception

正在引发的异常的堆栈跟踪如下:

java.util.concurrent.ExecutionException: java.lang.NullPointerException
    at com.google.firebase.tasks.Tasks.getResultOrThrowExecutionException(Tasks.java:179)
    at com.google.firebase.tasks.Tasks.await(Tasks.java:102)
    at com.google.firebase.internal.TaskToApiFuture.get(TaskToApiFuture.java:74)
    at com.newfaces.businesslogic.logic.MessageRequestLogicBean$1.run(MessageRequestLogicBean.java:75)
    at com.google.firebase.internal.TaskToApiFuture$1.onComplete(TaskToApiFuture.java:50)
    at com.google.firebase.tasks.OnCompleteCompletionListener$1.run(OnCompleteCompletionListener.java:54)
    at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:399)
    at com.google.firebase.tasks.OnCompleteCompletionListener.onComplete(OnCompleteCompletionListener.java:48)
    at com.google.firebase.tasks.TaskCompletionListenerQueue.flush(TaskCompletionListenerQueue.java:81)
    at com.google.firebase.tasks.TaskImpl.setException(TaskImpl.java:115)
    at com.google.firebase.tasks.Tasks$1.run(Tasks.java:84)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
    at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkNotNull(Preconditions.java:213)
    at com.google.api.client.util.Preconditions.checkNotNull(Preconditions.java:127)
    at com.google.api.client.json.jackson2.JacksonFactory.createJsonParser(JacksonFactory.java:98)
    at com.google.firebase.messaging.FirebaseMessaging.handleSendHttpError(FirebaseMessaging.java:251)
    at com.google.firebase.messaging.FirebaseMessaging.makeSendRequest(FirebaseMessaging.java:238)

我在FirebaseMessaging类中发现了引发此异常的根代码段:

  private void handleSendHttpError(HttpResponseException e) throws FirebaseMessagingException {
    MessagingServiceErrorResponse response = new MessagingServiceErrorResponse();
    try {
      JsonParser parser = jsonFactory.createJsonParser(e.getContent()); // HERE e.getContent() == null which throws the NullPointerException
      parser.parseAndClose(response);
    } catch (IOException ignored) {
      // ignored
    }

    String code = FCM_ERROR_CODES.get(response.getString("status"));
    if (code == null) {
      code = UNKNOWN_ERROR;
    }
    String msg = response.getString("message");
    if (Strings.isNullOrEmpty(msg)) {
      msg = String.format("Unexpected HTTP response with status: %d; body: %s",
          e.getStatusCode(), e.getContent());
    }
    throw new FirebaseMessagingException(code, msg, e);
  }

现在,鉴于此操作实际上未返回异常,因此无法进行调试,但我查看了Firebase API Metrics,发现服务器正在返回错误代码401 - Unauthorized。因此,为了验证这一点,我按照https://developers.google.com/cloud-messaging/http#checkAPIkey做了一个curl

# server_key=YOUR_SERVER_KEY

# curl --header "Authorization: key=$server_key" \
       --header Content-Type:"application/json" \
       https://gcm-http.googleapis.com/gcm/send \
       -d "{\"registration_ids\":[\"ABC\"]}"

我得到的答复是:

{"multicast_id":6706957967213497648,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1532214216265421%fa1b6a1df9fd7ecd"}]}

...表示该请求已针对我在应用程序中使用的给定server_key和registration_token(registration_id)被授权。

那让我完全迷失了。由于相同的令牌会从应用程序中获得Unathorized,因此curl被授权时,它是完全授权的。我不知道该如何进行,非常感谢您的帮助。

编辑

仅需提及的是,我还尝试了在有效的dryRun模式下运行。

0 个答案:

没有答案