Android의 기기 그룹 메시징

기기 그룹 메시징을 사용하면 그룹에 속한 기기에서 실행되는 앱의 여러 인스턴스에 단일 메시지를 보낼 수 있습니다. 보통 '그룹'은 단일 사용자에게 속한 여러 기기의 모음을 의미하지만 그룹의 모든 기기는 공통의 알림 키를 공유합니다. 이 키는 FCM이 그룹의 모든 기기에 메시지를 전달하는 데 사용하는 토큰입니다.

Admin SDK를 사용하거나 앱 서버에서 XMPP 또는 HTTP 프로토콜을 구현하면 기기 그룹 메시징을 사용할 수 있습니다. 알림 키 하나에 허용되는 최대 구성원 수는 20입니다.

기기 그룹 관리

기기 그룹에 메시지를 보내려면 먼저 다음을 수행해야 합니다.

  1. 그룹에 추가할 기기마다 등록 토큰을 받습니다.

  2. 보통은 사용자로 이루어진 특정 그룹을 그룹의 모든 관련 등록 토큰에 매핑하여 기기 그룹을 식별하는 notification_key를 만듭니다. 앱 서버나 Android 클라이언트 앱에서 알림 키를 만들 수 있습니다.

그룹 만들기, 그룹 삭제, 기기 추가 또는 기기 삭제와 같은 기본적인 기기 그룹 관리는 보통 앱 서버를 통해 수행합니다. 지원되는 키 목록은 HTTP 프로토콜 참조를 참조하세요.

Android 클라이언트 앱의 경우 선택적으로 클라이언트 쪽에서 기기 그룹을 관리할 수 있습니다.

앱 서버에서 기기 그룹 관리

기기 그룹 만들기

기기 그룹을 만들려면 그룹의 이름 및 기기의 등록 토큰 목록을 제공하는 POST 요청을 보내세요. 그러면 FCM이 기기 그룹을 나타내는 새 notification_key를 반환합니다.

HTTP POST 요청

https://fcm.googleapis.com/fcm/notification에 다음과 같이 요청을 보냅니다.

https://fcm.googleapis.com/fcm/notification
Content-Type:application/json
Authorization:key=API_KEY
project_id:SENDER_ID

{
   "operation": "create",
   "notification_key_name": "appUser-Chris",
   "registration_ids": ["4", "8", "15", "16", "23", "42"]
}

notification_key_name은 특정 그룹만의 이름 또는 식별자입니다. 예를 들어 사용자 이름일 수 있습니다. notification_key_namenotification_key는 등록 토큰 그룹에서 고유합니다. 동일한 발신자 ID에 대해 클라이언트 앱이 여러 개 있으면 notification_key_name이 클라이언트 앱별로 고유해야 합니다. 이 값이 고유해야 의도한 대상 앱으로만 메시지가 전달됩니다.

응답 형식

요청에 성공하면 다음과 같이 notification_key가 반환됩니다.

{
   "notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ"
}

notification_key 및 해당하는 notification_key_name을 저장하여 후속 작업에서 사용하세요.

알림 키 가져오기

기존 알림 키를 검색해야 하는 경우 다음과 같이 GET 요청에서 notification_key_name을 사용합니다.

https://fcm.googleapis.com/fcm/notification?notification_key_name=appUser-Chris
Content-Type:application/json
Authorization:key=API_KEY
project_id:SENDER_ID
{}

특정 알림 키 이름에 대한 각 GET 요청에 대해 서버는 고유한 인코딩 문자열을 반환합니다. 각 문자열이 다른 키로 보일 수 있지만 실제로는 유효한 `notification_key` 값입니다.

기기 그룹에서 기기 추가 및 삭제

기존 그룹에서 기기를 추가하거나 삭제하려면 operation 매개변수가 add 또는 remove로 설정된 POST 요청을 보내고 추가 또는 삭제용 등록 토큰을 제공하세요.

HTTP POST 요청

예를 들어 등록 ID가 51인 기기를 appUser-Chris에 추가하려면 다음 요청을 보냅니다.

{
   "operation": "add",
   "notification_key_name": "appUser-Chris",
   "notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ",
   "registration_ids": ["51"]
}

응답 형식

기기 추가 또는 삭제에 성공하면 다음과 같이 notification_key가 반환됩니다.

{
   "notification_key": "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ"
}

Android 클라이언트 앱에서 기기 그룹 관리

서버를 사용할 수 없는 경우에 클라이언트에서 기기 그룹을 관리하면 유용합니다. 클라이언트에서 기기 그룹을 만들려면 기기에 Google 계정이 1개 이상 있어야 합니다. 클라이언트에서 알림 키를 만드는 절차는 위에 설명되어 있는 서버 쪽 절차와 매우 다르다는 점에 유의하세요.

클라이언트에서 기기 그룹을 만드는 방법은 다음과 같습니다.

클라이언트 ID 받기

  1. Google Developers Console에서 프로젝트를 엽니다.
  2. 왼쪽 상단의 메뉴에서 API 및 서비스를 선택한 다음 사용자 인증 정보를 선택합니다.
  3. 새 사용자 인증 정보를 클릭하고 OAuth 클라이언트 ID를 선택합니다.
  4. 클라이언트 ID 만들기 대화상자에서 애플리케이션 유형으로 웹 애플리케이션을 선택하고 만들기를 클릭합니다.
  5. 클라이언트 ID로 표시되는 값을 복사합니다. 이 클라이언트 ID는 idToken을 생성하는 데 사용할 Google 계정 '범위'를 나타냅니다.

기기에서 Google 계정 유효성 검사

Google Developers Console에서 클라이언트 ID를 받고 나서 기기에 Google 계정이 있는지 확인하세요.

// This snippet takes the simple approach of using the first returned Google account,
// but you can pick any Google account on the device.
public String getAccount() {
    // This call requires the Android GET_ACCOUNTS permission
    Account[] accounts = AccountManager.get(this /* activity */).
            getAccountsByType("com.google");
    if (accounts.length == 0) {
        return null;
    }
    return accounts[0].name;
}

인증 토큰 가져오기

다음으로, GoogleAuthUtil 클래스를 사용하여 인증 토큰(idToken)을 가져옵니다. 예를 들면 다음과 같습니다.

String accountName = getAccount();

// Initialize the scope using the client ID you got from the Console.
final String scope = "audience:server:client_id:"
        + "1262xxx48712-9qs6n32447mcj9dirtnkyrejt82saa52.apps.googleusercontent.com";

String idToken = null;
try {
    idToken = GoogleAuthUtil.getToken(this, accountName, scope);
} catch (Exception e) {
    Log.w(TAG, "Exception while getting idToken: " + e);
}

그룹에서 기기 추가 또는 삭제

https://fcm.googleapis.com/fcm/googlenotification에 대한 HTTP POST 요청을 작성하여 그룹에 등록 토큰을 추가하거나 삭제합니다. 요청 헤더의 project_id발신자 ID로, Content-Type은 JSON으로 설정해야 합니다.

그룹에 추가

추가 작업에는 add로 설정된 operation, 위에서 받은 idToken으로 설정된 id_token, notification_key_name, registration_ids 등의 키가 필요합니다. 아래에 나와 있는 userEmail 변수는 accounts[0].name 값에서 가져올 수 있습니다. 클라이언트는 이 이메일이나 계정에 매핑된 그룹만 관리할 수 있도록 승인됩니다.

public String addToGroup(
        String senderId, String userEmail, String registrationId, String idToken)
        throws IOException, JSONException {
    URL url = new URL("https://fcm.googleapis.com/fcm/googlenotification");
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setDoOutput(true);

    // HTTP request header
    con.setRequestProperty("project_id", senderId);
    con.setRequestProperty("Content-Type", "application/json");
    con.setRequestProperty("Accept", "application/json");
    con.setRequestMethod("POST");
    con.connect();

    // HTTP request
    JSONObject data = new JSONObject();
    data.put("operation", "add");
    data.put("notification_key_name", userEmail);
    data.put("registration_ids", new JSONArray(Arrays.asList(registrationId)));
    data.put("id_token", idToken);

    OutputStream os = con.getOutputStream();
    os.write(data.toString().getBytes("UTF-8"));
    os.close();

    // Read the response into a string
    InputStream is = con.getInputStream();
    String responseString = new Scanner(is, "UTF-8").useDelimiter("\\A").next();
    is.close();

    // Parse the JSON string and return the notification key
    JSONObject response = new JSONObject(responseString);
    return response.getString("notification_key");
}

작업에 성공하면 notification_key가 반환됩니다. 이 notification_key 및 해당하는 notification_key_name을 저장하여 후속 작업에서 사용하세요.

그룹에서 제거

삭제 작업에는 remove로 설정된 operation, 위에서 받은 idToken으로 설정된 id_token, notification_key_name, registration_ids 등의 키가 필요합니다.

// HTTP request
JSONObject data = new JSONObject();
data.put("operation", "remove");
data.put("notification_key_name", userEmail);
data.put("registration_ids", new JSONArray(Arrays.asList(registrationId)));
data.put("id_token", idToken);

기기 그룹에 다운스트림 메시지 전송

기기 그룹에 메시지를 보내는 것은 개별 기기에 메시지를 보내는 것과 매우 비슷합니다. to 매개변수를 기기 그룹의 고유 알림 키로 설정하세요. 페이로드 지원의 자세한 내용은 메시지 유형을 참조하세요. 이 페이지의 예에서는 HTTP 및 XMPP 프로토콜로 기기 그룹에 메시지를 보내는 방법을 확인할 수 있습니다.

기기 그룹 HTTP POST 요청

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to": "aUniqueKey",
  "data": {
    "hello": "This is a Firebase Cloud Messaging Device Group Message!",
   }
}

기기 그룹 HTTP 응답

다음은 '성공' 응답의 예입니다. notification_key에 연결된 등록 토큰이 2개 있으며 메시지가 두 토큰에 모두 성공적으로 전송되었습니다.

{
  "success": 2,
  "failure": 0
}

다음은 '부분적인 성공' 응답의 예입니다. notification_key에 연결된 등록 토큰이 3개 있습니다. 메시지가 등록 토큰 1개에만 성공적으로 전송되었습니다. 메시지를 수신하지 못한 등록 토큰이 응답 메시지에 표시됩니다.

{
  "success":1,
  "failure":2,
  "failed_registration_ids":[
     "regId1",
     "regId2"
  ]
}

메시지가 notification_key에 연결된 1개 이상의 등록 토큰에 전송되지 못하면 앱 서버에서 일정한 간격을 두고 재시도해야 합니다.

서버에서 메시지를 보내려는 기기 그룹에 구성원이 없는 경우 다음과 같이 응답의 성공, 실패가 모두 0입니다.

{
  "success": 0,
  "failure": 0
}

기기 그룹 XMPP 메시지

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to": "aUniqueKey",
      "message_id": "m-1366082849205" ,
      "data": {
          "hello":"This is a Firebase Cloud Messaging Device Group Message!"
      }
  }
  </gcm>
</message>

기기 그룹 XMPP 응답

그룹에 메시지가 성공적으로 전송된 기기가 있으면 XMPP 연결 서버가 ACK로 응답합니다. 모든 메시지가 그룹의 모든 기기에 전송되지 못하면 XMPP 연결 서버가 NACK으로 응답합니다.

다음은 '성공' 응답의 예입니다. notification_key에 연결된 등록 토큰이 3개 있으며 메시지가 모든 토큰에 성공적으로 전송되었습니다.

{
  "from": "aUniqueKey",
  "message_type": "ack",
  "success": 3,
  "failure": 0,
  "message_id": "m-1366082849205"
}

다음은 '부분적인 성공' 응답의 예입니다. notification_key에 연결된 등록 토큰이 3개 있습니다. 메시지가 등록 토큰 1개에만 성공적으로 전송되었습니다. 응답 메시지에 메시지를 수신하지 못한 등록 토큰이 표시됩니다.

{
  "from": "aUniqueKey",
  "message_type": "ack",
  "success":1,
  "failure":2,
  "failed_registration_ids":[
     "regId1",
     "regId2"
  ]
}

FCM 연결 서버가 그룹의 모든 기기에 전송하지 못하면 앱 서버가 NACK 응답을 수신합니다.

메시지 옵션의 전체 목록은 HTTP 또는 XMPP 중 선택한 연결 서버 프로토콜에 맞는 참조 정보를 확인하세요.

기기 그룹에 업스트림 메시지 전송

to 필드의 적절한 알림 키에 메시지를 타겟팅하면 클라이언트 앱이 기기 그룹으로 업스트림 메시지를 보낼 수 있습니다.

다음과 같이 FCM을 호출하면 알림 키에 업스트림 메시지가 전송됩니다. 객체는 키-값 쌍으로 구성됩니다.

String to = "a_unique_key"; // the notification key
AtomicInteger msgId = new AtomicInteger();
FirebaseMessaging.getInstance().send(new RemoteMessage.Builder(to)
        .setMessageId(String.valueOf(msgId.get()))
        .addData("hello", "world")
        .build());

다음에 대한 의견 보내기...

도움이 필요하시나요? 지원 페이지를 방문하세요.