0

當過Google Firebase Cloud Messaging將通知發送給收件人單一,有時一個響應返回(200 + error:MissingRegistration200 + error:InvalidRegistration200 + error:NotRegistered),這需要刪除收件人的令牌(因爲她例如重新安裝Android應用程序和令牌已經改變)。如何將用戶上下文對象傳遞給異步Jetty HTTP客戶端的響應回調?

我的問題是:

如何傳遞字符串(FCM令牌)回的無阻塞Jetty HTTP client響應回調?

目前我的解決方法是將一個自定義HTTP標頭添加到我的要求:

X-token: APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx... 

,然後我在響應回調檢索。但是這是一個破解,因爲FCM沒有指定這樣的頭文件,而且我需要將更多的自定義數據(我的應用程序中的內部用戶ID)傳回。

這裏是my current source code與自定義HTTP標頭,請問如何改變它?

private static final String FCM_URL     = "https://fcm.googleapis.com/fcm/send"; 
private static final String FCM_KEY     = "key=REPLACE_BY_YOUR_KEY"; 
private static final String FCM_RESULTS    = "results"; 
private static final String FCM_ERROR    = "error"; 
private static final String FCM_NOT_REGISTERED  = "NotRegistered"; 
private static final String FCM_MISSING_REGISTRATION = "MissingRegistration"; 
private static final String FCM_INVALID_REGISTRATION = "InvalidRegistration"; 

private static final String FCM_X_TOKEN    = "X-token"; 
private static final String TOKEN     = "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx..."; 

private static final Map<String, Object> REQUEST  = new HashMap<>(); 
private static final Map<String, Object> NOTIFICATION = new HashMap<>(); 
private static final Map<String, Object> DATA   = new HashMap<>(); 

static { 
    REQUEST.put("to", TOKEN); 
    REQUEST.put("notification", NOTIFICATION); 
    REQUEST.put("data", DATA); 
    NOTIFICATION.put("body", "great match!"); 
    NOTIFICATION.put("title", "Portugal vs. Denmark"); 
    NOTIFICATION.put("icon", "myicon"); 
    DATA.put("Nick", "Mario"); 
    DATA.put("Room", "PortugalVSDenmark"); 
} 

private static final SslContextFactory sFactory = new SslContextFactory(); 
private static final HttpClient sHttpClient = new HttpClient(sFactory); 
private static final BufferingResponseListener sFcmListener = new BufferingResponseListener() { 
    @Override 
    public void onComplete(Result result) { 
     if (!result.isSucceeded()) { 
      System.err.println(result.getFailure()); 
      return; 
     } 

     String body = getContentAsString(StandardCharsets.UTF_8); 

     try { 
      Map<String, Object> resp = (Map<String, Object>) JSON.parse(body); 
      Object[] results = (Object[]) resp.get(FCM_RESULTS); 
      Map map = (Map) results[0]; 
      String error = (String) map.get(FCM_ERROR); 
      System.out.printf("error: %s\n", error); 
      if (FCM_NOT_REGISTERED.equals(error) || 
       FCM_MISSING_REGISTRATION.equals(error) || 
       FCM_INVALID_REGISTRATION.equals(error)) { 
       String token = result.getRequest().getHeaders().get(FCM_X_TOKEN); 
       System.out.printf("TODO delete invalid FCM token from the database: %s\n", token); 
      } 
     } catch (Exception ex) { 
      System.err.println(ex); 
     } 
    } 
}; 

public static void main(String[] args) throws Exception { 
    sHttpClient.start(); 
    sHttpClient.POST(FCM_URL) 
     .header(HttpHeader.AUTHORIZATION, FCM_KEY) 
     .header(HttpHeader.CONTENT_TYPE, "application/json") 
     .header(FCM_X_TOKEN, TOKEN) // Workaround, how to improve? 
     .content(new StringContentProvider(JSON.toString(REQUEST))) 
     .send(sFcmListener); 
} 

回答

1

你要設置的令牌作爲請求屬性和檢索回:

httpClient.POST(url) 
     .attribute(key, token) 
     ... 
     .send(new BufferingResponseListener() { 
      @Override 
      public void onComplete(Result result) { 
       Object token = result.getRequest().getAttribute(key); 
       ... 
      } 
     }); 
+0

謝謝,我已經使用'字符串令牌=將String.valueOf(result.getRequest() .getAttributes()。get(key));' –