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));' –

相关问题