어서와, 개발은 처음이지?

React Native Firebase 푸시 알림(push notification), background listener - 3.서버 구현 본문

React/React Native

React Native Firebase 푸시 알림(push notification), background listener - 3.서버 구현

오지고지리고알파고포켓몬고 2019. 4. 11. 23:07
반응형



이 글은

React Native Firebase 푸시 알림(push notification), background listener - 1.Android 세팅

React Native Firebase 푸시 알림(push notification), background listener - 2.firebase 리스너 구현

React Native Firebase 푸시 알림(push notification), background listener - 3.서버 구현(현재글)로 구성되어 있습니다.




이번 글에서는 node 서버단에서 firebase에 메세지 전송을 요청할 수 있도록 구현하고, 메세지가 잘 도착하는지 확인해보는 작업을 해보겠습니다.



1. 프로젝트 생성


우선 프로젝트를 생성하고, express.js와 firebase-admin sdk를 설치하도록 합니다.

> mkdir FirebaseServer && cd FirebaseServer
> npm init
> npm install --save express firebase-admin



2. 인증정보 생성


Firebase 콘솔에 접속하여, 프로젝트의 설정 페이지에서 서비스 계정 탭으로 이동합니다.

그리고 새 비공개 키 생성을 눌러서 인증정보를 다운받습니다.

그리고 다운 받은 인증정보를 FirebaseServer 하위에 위치하도록 이동시켜 놓습니다.



3. 데이터베이스 생성


sdk를 초기화 할때 필요한 database url 입력을 위해 데이터베이스를 생성합니다.


Firebase 콘솔의 좌측 메뉴에서 Database를 선택하고, 테스트 모드로 생성해봅니다.(실제 서비스에서는 잠금 모드로 시작하세요!)

생성이 완료되면 아래와 같은 화면을 볼 수 있는데, 빨간색으로 표시한 부분이 database name입니다.

https://<DATABASE_NAME>.firebaseio.com에 본인의 database name을 넣으면 되겠습니다.



4. app.js 생성


다시 프로젝트로 돌아와서 app.js를 생성해줍니다.

const express = require('express');
const admin = require('firebase-admin')
const serviceAccount = require('./fir-test-ceff6-firebase-adminsdk-lf11h-4c17576652.json');

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: 'https://fir-test-ceff6.firebaseio.com'
});

const app = express();
app.get('/:token',function(req,res){
    const message = {
        data: {
          score: '850',
          time: '2:45'
        },
        token: req.params.token,
    };

    admin.messaging().send(message)
    .then((response) => {
        // Response is a message ID string.
        console.log('Successfully sent message:', response);
    })
    .catch((error) => {
        console.log('Error sending message:', error);
    });
});

app.listen(3000, function(){
    console.log(`Connect 3000 port!`)
});

서버단은 token값을 라우트로 받아서, 해당 토큰에 message를 푸시하는 기능을 수행합니다.


이제 app.js를 실행합니다.

> node app.js
Connect 3000 port!




5. 메세지 보내기


이제 지난 글에서 작업했던 React Native 앱을 실행합니다.


우선 디버깅 모드를 실행해서 token 값을 확인해봅니다.


다음으로 이 토큰 값을 node 서버에 요청합니다.(편의상 브라우저로 요청했습니다.)


다음으로 서버의 콘솔을 확인해보면 메세지를 전송했다는 로그를 확인할 수 있습니다.

마지막으로 React Native 앱의 디버깅 콘솔을 확인해보면 메세지가 정상적으로 수신 되는 모습을 볼 수 있습니다.


data 객체에 score와 time이 포함된 모습이 보입니다.



일반 푸시 알림은 아래와 같은 형식으로 보낼 수 있습니다.

app.get('/:token',function(req,res){
    const message = {
        data: {
          score: '850',
          time: '2:45'
        },
        android: {
            ttl: 3600 * 1000, // 1 hour in milliseconds
            priority: 'normal',
            notification: {
              title: '$GOOG up 1.43% on the day',
              body: '$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
              color: '#f45342'
            }
        },
        token: req.params.token,
    };

    admin.messaging().send(message)
    .then((response) => {
        // Response is a message ID string.
        console.log('Successfully sent message:', response);
    })
    .catch((error) => {
        console.log('Error sending message:', error);
    });
});

<FirbaseServer/app.js>



다시 말씀드리면, FCM notification은 3가지 종류가 있습니다.


  • notification-only messages from FCM
  • notification + data messages from FCM
  • local notifications

알림을 사용하여 알림을 보낼때는 message 객체의 구성에 따라 구분되게 됩니다.


그러므로 message 객체를 구성할 수 있는 요소는 공식 문서에서 참고하시어, 직접 커스텀 해보시기 바랍니다.




6. background listener 확인


이제 지난번에 만든 background listener가 message를 정상적으로 핸들링 하는지 확인해보도록 하겠습니다.


우선 FirebaseServer의 app.js를 아래와 같이 수정합니다.

const express = require('express');
const admin = require('firebase-admin')
const serviceAccount = require('./fir-test-ceff6-firebase-adminsdk-lf11h-4c17576652.json');

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: 'https://fir-test-ceff6.firebaseio.com'
});

const app = express();
app.get('/:token',function(req,res){
    const message = {
        data: {
          status: 'emergency',
          contact: 'yuddomack'
        },
        token: req.params.token,
    };

    admin.messaging().send(message)
    .then((response) => {
        // Response is a message ID string.
        console.log('Successfully sent message:', response);
    })
    .catch((error) => {
        console.log('Error sending message:', error);
    });
});

app.get('/emergency/:contact',function(req,res){
    const {contact} = req.params;
    console.log(`rescue request to ${contact}`);

    res.send({code: '200'});
});

app.listen(3000, function(){
    console.log(`Connect 3000 port!`)
});

<FirebaseServer/app.js>


다음은 FirebaseTest의 bgMessaging.js를 아래와 같이 수정합니다.

import firebase from 'react-native-firebase';
// import RNImmediatePhoneCall from 'react-native-immediate-phone-call';

export default async (message) => {
    // handle your message
    // you can't see this message, because debugger may off when app closed
    // but you can use react native code like fetch, etc ... 
    
    const {contact} = message.data;
    await fetch(`http://192.168.219.164/emergency/${contact}`);
    /*
    RNImmediatePhoneCall.immediatePhoneCall(contact);
    */

    return Promise.resolve();
}

<FirebaseTest/bgMessaging.js>


앱을 리로드 한 뒤에, 이번에는 앱을 종료시켜줍니다.


다시 토큰 값을 서버에 요청하면 앱이 활성화 되어있지 않음에도 다음과 같이 서버에 fetch 요청되는 모습을 볼 수 있습니다.

이러한 과정은 앱에 어떤 이벤트(구조 요청같은)가 발생했을때, 앱에서 즉시 전화연결을 하도록 하는 식을 모의한 내용이였습니다.(react-native-immediate-phone-call)


여러분이 구현하시려는 앱에 백그라운드에서 즉시 대응해아하는 기능이 필요할 경우 적용하시면 되겠습니다.



7. 마치며


여기까지 node 서버에서 firebase sdk를 통해 앱에 푸시 알림을 보내는 방법에 대하여 알아봤습니다.


다음에는 마지막으로 ios에서 알림을 수신하는 방법을 알아보겠습니다.



8. 참조


Firebase 공식 홈페이지





Comments