여러 기기에 메시지 보내기

Firebase 클라우드 메시징에서는 2가지 방법을 사용해서 메시지를 여러 기기로 타겟팅합니다.

  • 주제 메시징: 특정 주제를 구독하는 여러 기기에 메시지를 보낼 수 있습니다.
  • 기기 그룹 메시징: 내가 정의하는 그룹에 속한 여러 기기에 메시지를 보낼 수 있습니다.

이 가이드에서는 앱 서버에서 FCM용 HTTP 또는 XMPP 프로토콜을 사용하여 주제 메시지를 보내는 방법 및 웹 앱에서 메시지를 수신하고 처리하는 방법을 중점적으로 설명하며 백그라운드 앱과 포그라운드 앱의 메시지 처리 방법을 모두 설명합니다.

SDK 설정

FCM을 위한 자바스크립트 클라이언트 앱 설정 또는 메시지 수신 단계를 마친 경우 이 섹션에서 다루는 단계를 이미 완료한 상태일 수 있습니다.

자바스크립트 프로젝트에 Firebase 추가

아직 추가하지 않았다면 자바스크립트 프로젝트에 Firebase를 추가합니다.

메시지 수신을 위해 브라우저 구성

FCM에서 이 앱에 메시지를 보내도록 승인한다는 의미로 gcm_sender_id 하드 코딩 값을 지정하는 웹 앱 매니페스트를 추가해야 합니다. 앱에 이미 manifest.json 구성 파일이 있는 경우 값을 변경하지 말고 아래와 동일하게 브라우저 발신자 ID를 추가하세요.

{
  "gcm_sender_id": "103953800507"
}

메시징 객체 검색

// Retrieve Firebase Messaging object.
const messaging = firebase.messaging();

알림 수신 권한 요청

messaging.requestPermission() 메소드는 앱이 브라우저의 알림을 수신할 수 있는 권한을 부여하도록 사용자에게 요청하는 동의 대화상자를 표시합니다. 권한이 거부되면 FCM 등록 토큰 요청으로 인해 오류가 발생합니다.

messaging.requestPermission().then(function() {
  console.log('Notification permission granted.');
  // TODO(developer): Retrieve an Instance ID token for use with FCM.
  // ...
}).catch(function(err) {
  console.log('Unable to get permission to notify.', err);
});

등록 토큰 액세스

이 섹션에서는 앱 인스턴스의 등록 토큰을 검색하고 토큰 새로고침 이벤트를 모니터링하는 방법을 설명합니다. 최초 시작 후에 토큰이 회전될 수 있으므로 토큰 새로고침을 모니터링하면서 항상 최신 상태로 업데이트된 등록 토큰을 검색해야 합니다.

다음과 같은 경우에 등록 토큰이 변경될 수 있습니다.

  • 웹 앱이 등록 토큰을 삭제할 때
  • 사용자가 브라우저 데이터를 소거할 때. 이 경우 getToken을 호출하여 새 토큰을 검색하세요.

현재 등록 토큰 검색

현재 토큰을 검색하려면 getToken을 호출합니다. 권한이 부여되지 않았다면 이 메소드는 null을 반환합니다. 그렇지 않은 경우 토큰을 반환하거나 오류가 있으면 프라미스를 거부합니다.

메시징 서비스에 firebase-messaging-sw.js 파일이 필요합니다. firebase-messaging-sw.js 파일이 아직 없다면 토큰을 검색하기 전에 해당 이름의 빈 파일을 만들어 도메인의 루트에 저장합니다. 나중에 클라이언트 설정 프로세스에서 중요한 내용을 추가할 수 있습니다.

다음과 같이 현재 토큰을 검색할 수 있습니다.

// Get Instance ID token. Initially this makes a network call, once retrieved
// subsequent calls to getToken will return from cache.
messaging.getToken().then(function(currentToken) {
  if (currentToken) {
    sendTokenToServer(currentToken);
    updateUIForPushEnabled(currentToken);
  } else {
    // Show permission request.
    console.log('No Instance ID token available. Request permission to generate one.');
    // Show permission UI.
    updateUIForPushPermissionRequired();
    setTokenSentToServer(false);
  }
}).catch(function(err) {
  console.log('An error occurred while retrieving token. ', err);
  showToken('Error retrieving Instance ID token. ', err);
  setTokenSentToServer(false);
});

토큰 새로고침 모니터링

토큰이 새로 생성될 때마다 onTokenRefresh 콜백이 실행되므로 이 콜백의 컨텍스트에서 getToken을 호출하면 사용 가능한 현재 등록 토큰에 항상 액세스하게 됩니다.

// Callback fired if Instance ID token is updated.
messaging.onTokenRefresh(function() {
  messaging.getToken().then(function(refreshedToken) {
    console.log('Token refreshed.');
    // Indicate that the new Instance ID token has not yet been sent to the
    // app server.
    setTokenSentToServer(false);
    // Send Instance ID token to app server.
    sendTokenToServer(refreshedToken);
    // ...
  }).catch(function(err) {
    console.log('Unable to retrieve refreshed token ', err);
    showToken('Unable to retrieve refreshed token ', err);
  });
});

토큰이 확보되었으면 앱 서버로 전송하고 원하는 방법으로 저장하세요. Instance ID server API를 사용하여 구독 관련 정보를 가져올 수 있습니다.

클라이언트 앱에서 주제 구독

등록 토큰과 주제 이름이 주어지면 Google Instance ID server API를 사용하여 주제에 토큰을 추가할 수 있습니다. 이 엔드포인트에서 Instance ID API를 호출하면서 앱 인스턴스의 등록 토큰과 주제 이름을 제공하면 됩니다.

 https://iid.googleapis.com/iid/v1/<REGISTRATION_TOKEN>/rel/topics/<TOPIC_NAME>

예를 들어 앱 인스턴스에서 'movies'라는 주제를 구독하려면 아래와 같이 서버에서 엔드포인트에 POST 요청을 전송하면서 인증 헤더에 서버 API 키를 추가합니다.

https://iid.googleapis.com/iid/v1/nKctODamlM4:CKrh_PC8kIb7O...clJONHoA/rel/topics/movies
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

서버 키는 기밀 정보이므로 어떠한 경우에도 클라이언트에서 이러한 유형의 요청을 전송하지 마세요.

요청에 성공하면 HTTP 200 OK가 반환됩니다. 오류 응답 및 일괄 요청 전송 방법에 관한 자세한 내용은 앱 인스턴스의 관계 맵 만들기를 참조하세요.

주제 메시지 수신 및 처리

메시지의 동작은 페이지가 포커스를 갖는 포그라운드 상태인지, 백그라운드 상태인지, 다른 탭 뒤에 숨겨져 있는지, 완전히 닫혀 있는지에 따라 다릅니다. 어떠한 경우든 페이지는 onMessage 콜백을 처리해야 하며, 백그라운드 상태인 경우에는 setBackgroundMessageHandler를 처리하거나 사용자가 웹 앱을 포그라운드로 전환할 수 있도록 디스플레이 알림을 구성해야 할 수도 있습니다.

앱 상태 알림 데이터 모두
포그라운드 onMessage onMessage onMessage
백그라운드(서비스 워커) SDK가 표시하는 알림 setBackgroundMessageHandler SDK가 표시하는 알림

웹 앱이 포그라운드 상태일 때 메시지 처리

onMessage 이벤트를 수신하려면 앱에서 firebase-messaging-sw.js에 Firebase 메시징 서비스 워커를 정의해야 합니다. useServiceWorker를 사용하여 기존 서비스 워커를 지정할 수도 있습니다.

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
  'messagingSenderId': 'YOUR-SENDER-ID'
});

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();

앱이 포그라운드 상태일 때, 즉 사용자가 현재 웹페이지를 보고 있을 때는 데이터 및 알림 페이로드를 페이지에서 직접 수신할 수 있습니다.

// Handle incoming messages. Called when:
// - a message is received while the app has focus
// - the user clicks on an app notification created by a service worker
//   `messaging.setBackgroundMessageHandler` handler.
messaging.onMessage(function(payload) {
  console.log('Message received. ', payload);
  // ...
});

웹 앱이 백그라운드 상태일 때 메시지 처리

앱이 백그라운드 상태일 때 수신된 모든 메시지는 브라우저의 디스플레이 알림을 트리거합니다. 앱 서버의 전송 요청이나 클라이언트의 서비스 워커 로직을 사용하여 제목, 클릭 동작 등의 알림 관련 옵션을 지정할 수 있습니다.

전송 요청에 알림 옵션 설정

앱 서버에서 알림 메시지를 전송하는 경우 FCM JavaScript API는 click_action 키를 지원합니다. 일반적으로 이 키는 웹 앱의 페이지로 설정됩니다.

https://fcm.googleapis.com//v1/projects/<YOUR-PROJECT-ID>/messages:send
Content-Type: application/json
Authorization: bearer <YOUR-ACCESS-TOKEN>

{
  "message": {
    "topic": "matchday"
    "notification": {
      "title": "Background Message Title",
      "body": "Background message body"
    },
    "webpush": {
      "fcm_options": {
        "link": "https://dummypage.com"
      }
    }
  }
}

클릭 동작이 브라우저 탭에 이미 열려 있는 페이지를 가리키면 알림을 클릭할 때 해당 탭이 포그라운드로 전환됩니다. 페이지가 열려 있지 않은 경우 알림을 클릭하면 새 탭에서 페이지가 열립니다.

데이터 메시지는 click_action을 지원하지 않으므로 모든 데이터 메시지에 알림 페이로드를 추가하는 것이 좋습니다. 서비스 워커를 사용하여 알림을 처리할 수도 있습니다.

알림과 데이터 메시지의 차이점에 대한 설명은 메시지 유형을 참조하세요.

서비스 워커에서 알림 옵션 설정

알림 메시지와 데이터 메시지 모두에 대해 서비스 워커에서 알림 옵션을 설정할 수 있습니다. 우선 서비스 워커에서 앱을 초기화합니다.

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
  'messagingSenderId': 'YOUR-SENDER-ID'
});

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();

옵션을 설정하려면 firebase-messaging-sw.js에서 setBackgroundMessageHandler를 호출합니다. 이 예에서는 제목, 본문, 아이콘 및 클릭 동작 옵션을 설정합니다.

messaging.setBackgroundMessageHandler(function(payload) {
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  var notificationTitle = 'Background Message Title';
  var notificationOptions = {
    body: 'Background Message body.',
    icon: '/firebase-logo.png'
  };

  return self.registration.showNotification(notificationTitle,
    notificationOptions);
});

보내기 요청 작성

서버 쪽에서 Firebase 클라우드 메시징 주제로 메시지를 보내는 것은 개별 기기나 사용자 그룹으로 메시지를 보내는 것과 매우 비슷합니다. 앱 서버는 to 키를 /topics/yourTopic 등의 값으로 설정합니다. 개발자는 다음 정규 표현식과 일치하는 모든 주제 이름을 선택할 수 있습니다. "/topics/[a-zA-Z0-9-_.~%]+"

주제 HTTP POST 요청

POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
  "message":{
    "topic" : "foo-bar",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message",
      }
   }
}

cURL로 보내는 방법은 다음과 같습니다.

curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
  "notification": {
    "title": "FCM Message",
    "body": "This is a Firebase Cloud Messaging Topic Message!",
  },
  "topic" : "foo-bar"
}' "https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1"

주제 HTTP 응답

{
    "name": "projects/myproject-b5ae1/messages/5735743068807585451"
}

주제 XMPP 메시지

주제 1개로 보내는 방법은 다음과 같습니다.

<message id="">
  <gcm xmlns="google:mobile:data">
{
  "to" : /topics/foo-bar",
  "priority" : "high",
  "notification" : {
    "body" : "This is a Firebase Cloud Messaging Topic Message!",
    "title" : "FCM Message",
  }
}
  </gcm>
</message>

주제 XMPP 응답

//Success example:
{
  "message_id": "1023456"
}

//failure example:
{
  "error": "TopicsMessageRateExceeded"
}

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

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