kokbee-Hive
article thumbnail

이전 글에 이어서 이번에 안드로이드용 푸시에 대해서 진행했던 내용을 기록 및 공유합니다.

 

* 참고: firebase 사이트에서 앱 등록 및 세팅 다 가정되어 있고 그 이후에 내용입니다.

 

1.  개발 진행 전


  1.  요구사항 분석 (Android)
    1.  기존 백오피스에서 사용하던 올드한 방식의 푸시를 간편하게 개선
    2.  기존 모듈의 최신화 또는 새로운 모듈로 변경 (node-gcm) 의경우 2년 전에 Deprecated (node-gcm 이전에는 node-fcm에 있엇음 병합된 모듈 레포) https://www.npmjs.com/package/node-gcm
      1. firebase-admin이라는 모듈로 변경 https://www.npmjs.com/package/firebase-admin
    3.  타이틀 추가 및 bold 기능 (subtitle or title로 가능), 줄바꿈
 

node-gcm

Easy interface for Google's Cloud Messaging service (now Firebase Cloud Messaging). Latest version: 1.0.5, last published: 2 years ago. Start using node-gcm in your project by running `npm i node-gcm`. There are 155 other projects in the npm registry using

www.npmjs.com

 

firebase-admin

Firebase admin SDK for Node.js. Latest version: 11.5.0, last published: 2 months ago. Start using firebase-admin in your project by running `npm i firebase-admin`. There are 2351 other projects in the npm registry using firebase-admin.

www.npmjs.com

 

2.  모듈 교체 및 코드 작성


* ios 할때와 플로우는 비슷하기 때문에 스킵합니다.
https://kokbee.tistory.com/2 페이지를 보고 와주시면 감사하겠습니다. 🙇‍♂️


임시로 블로그에 올리려고 짠 코드입니다.
대충 이런 느낌이라고 보시면 될것 같습니다.

const fcm = require('firebase-admin')

// 공통적으로 500개를 맥스 값으로 선언
const MAX_TOKEN_SIZE = 500
const defaultCert = require('./default.json')
const otherCert = require('./other.json')

const defaultApp = fcm.initializeApp({
  credential: fcm.credential.cert(defaultCert)
}, 'default')
const otherApp = fcm.initializeApp({
  credential: fcm.credential.cert(otherCert)
}, 'other')

async function sendNoti(options) {
  const notification = { body: options.body ?? 'Notification' }
  if (options.title) notification.title
  const message = {
    notification,
    data: { ...notification },
    android: {
      ttl: options.ttl,
      collapseKey: options.collapseKey
    }
  }

  let fcmProvider = defaultApp.messaging()
  if (!options.is_default) fcmProvider = otherApp.messaging()

  const tokenList = options.device_list.map((device) => device.device_token)
  if (tokenList.length > MAX_TOKEN_SIZE) {
    // 토큰갯수가 맥스값을 넘은경우
    const tasks = []
    for (let i = 0; i < tokenList.length; i += MAX_TOKEN_SIZE) {
      const batch = tokenList.slice(i, i + MAX_TOKEN_SIZE)
      tasks.push(batch)
    }

    await Promise.all(tasks.map((tokens) => {
      const batchMessage = Object.assign({}, message, { tokens })
      return fcmProvider.sendMulticast(batchMessage)
    })).then((responses) => {
        responses.forEach((batchResponse, index) => {
          if (batchResponse.failureCount > 0) {
            batchResponse.responses.forEach((sendResponse, index) => {
              if (sendResponse.error) {
                console.error(`Failed to send message to ${message.tokens[index]}: ${sendResponse.error}`)
              }
            })
          }
        })
      }).catch((error) => console.error('sending message error:', error))
  } else if (tokenList.length > 0) {
    message.tokens = tokenList
    await fcmProvider.sendMulticast(message)
      .then((batchResponse) => {
        batchResponse.responses.forEach((sendResponse, index) => {
          if (sendResponse.error) {
            console.error(`Failed to send message to ${message.tokens[index]}: ${sendResponse.error}`)
          }
        })
      })
  } else {
    return 
  }
}

설명

  1. fcm에서는 sendMulticast() 함수를 이용해 토큰을 다수값으로 넣어서 500개단위로 보낼 수 잇음 (광고성 푸시에 적합)
    1. send(), sendAll()도 있지만 단일 토큰 기준입니다.
  2. fcm에서는 Notification 에 title, body입력시 볼드와 메시지 내용 입력가능

 

3.  테스트 및 결과


조금 애를 먹긴했지만 성공했다.

 

ios보다는 쉬웟는데.. 진행하다 에로 사항이 있었다. 에로 사항은 아래 사진과 같다.

이유는 API를 사용하는 권한이 없는것..

Why? key를 받앗는데..?

 

알고보니 키는 받았어도 서비스계정에 sdk를 사용할 권한을 활성화 해줘야햇던것...

이렇게 해주고 몇분 기다려보니 잘 푸시가 보내졋다!

ios, fcm 둘다 보내게도 해봣는데 문제 없음 😎

 

암튼 이렇게 해서 fcm까지 끝냇다.

 

 

이상으로 포스팅을 마칩니다. part.3 로 찾아뵙겟습니다.

profile

kokbee-Hive

@콕비

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!