[이타인클럽앱] Cloud Functions을 이용한 Push Notification 구현 1/3

in #busy5 years ago (edited)

한 사용자가 다수의 사용자에게 Push notification을 보내는 방법입니다. 이전에는 Firebase의 Cloud Messaging 콘솔에서 메시지 보내고 사용자 기기에서 수신하는 방법을 알아봤었습니다. 이번에는 콘솔을 이용하지 않고, 사용자 앱에서 보내는 것을 구현합니다.

총 3편으로 구성될 예정입니다.

개발환경

  • React Native: 안드로이드와 iOS 공통 플랫폼
  • Ubuntu 18.04: React Native는 OS에 구별받지 않지만, 편의상 리눅스 기반에서 작업
  • Android Studio: iOS 기기가 없어 우선 Android 기기에서 개발
  • Firebase
    • Authentication: 사용자 가입, 로그인
    • Database -> Firestore: 사용자 기기의 push token, 메시지 기록
    • Cloud Messaging: 클라우드 메시지 송수신
    • Functions: 웹 Backend 기능.
  • react-native-firebase (v5.x.x): firebase에서 공식적으로 React Native를 지원하지 않고 있습니다. 그러나 react-native-firebase 라이브러리를 추천하고 있습니다. 아래 구현 방법은 'firebase'를 사용하면 안됩니다. 매우 중요합니다.

메시지 전송 흐름

사용자간 메시지를 전송하는 방법은 몇 가지가 있을 수 있지만, 안전하게 보내는 방법은 Firebase의 Cloud Messaging을 이용하는 것입니다.

  1. 사용자 신규 가입
    • Authentication: 사용자 등록
    • 사용자 기기의 Push 토큰을 생성하여 Firestore DB(예 users)에 저장
    • Authentication에서는 별도의 사용자 DB를 자동으로 생성하지 않음
      2 사용자가 메시지 작성
  2. 작성한 메시지를 Firestore에 저장
  3. Functions 함수가 Firestore에 새로운 메시지가 들어오면 메시지 송신 요청 함수 실행
    • 앱 사용자의 Push Token과 함께 메시지 내용을 Cloud Messaging에 전송
  4. Cloud Messaging이 알아서 다수의 앱 사용자에게 메시지 전송

아래 그림이 상황은 조금 다르지만 이와 같은 프로세스를 설명하고 있습니다.
image.png

핵심은 앱 사용자의 push 토큰을 DB에 저장하고, 메시지를 저장하는 별도의 DB를 만들고, 메시지 DB가 업데이트 되면, Functions이 이를 인지하여 Cloud Messaging에 메시지를 보내도록 하는 것입니다.

이 때, 중요한 것이 기기의 push 토큰입니다. 토큰이 있어야 메시지를 송수신 할 수 있습니다.

react-native-firebase 설치 및 설정

아래와 같이 프로젝트를 만들고 react-native-firebase를 설치합니다.
$ yarn add react-native-firebase
$ react-native link react-native-firebase

Cloud Messaging 설정

Firebase Cloud Messaging을 위한 기본 설정은 이전글을 참고하세요.
React-Native 이타인클럽 앱 Firebase Cloud Messaging Setup
React-Native 이타인클럽 앱 Firebase Cloud Messaging Test

Firebase Functions 설정

Firebase Functions은 별도의 서버 구축없이 backend 서버에서 필요한 일들을 가능하게 합니다. 일종의 cloud 서버 같습니다. 그러나 별도로 서버 구축이나 이런 부분 없이 바로 서비스에 필요한 기능만 구현하면 되니깐 매우 편리합니다.
프로젝트 폴더로 이동하여 아래와 같이 실행합니다.

$ yarn global add firebase-tools

firebase에 로그인합니다.

$ firebase login

로그인하면 아래 그림처럼 콘솔에서 firebase functions을 설정합니다.

$ firebase init functions

image.png

초기 설정에서 사용언어라던지 ESLint 설정이라던지 물어보는데 개발환경에 맞게 설정합니다.

자세한 내용은 아래를 참고하세요.
https://firebase.google.com/docs/functions/get-started
https://agostini.tech/2018/09/16/using-firebase-cloud-functions/

위와 같이 설정하면 프로젝트 폴더 밑에 functions이라는 폴더가 생깁니다.

image.png

Firestore 설정

Firestore는 Database (DB)입니다. Firebase는 두 개의 DB 타입이 있습니다.

  • Realtime Database
  • Cloud Firestore

Firebase의 최신 DB는 Firestore라고 하니 여기서도 Firestore를 사용합니다. 이것도 주의하셔야 합니다. 기존 문서들은 Realtime Database를 사용한 경우가 많습니다.

Firestore 설정은 특별한 것이 없고, 다음에서 설명하는 Android Studio 설정만 하면 됩니다.

Android Studio에서 Firebase 설정

project build.gradle 파일

(생략)
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.2'
        classpath 'com.google.gms:google-services:4.2.0'
(생략)
allprojects {
    repositories {
        mavenLocal()
        google()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}

app build.gradle 파일

react-native-firebase는 사용하고자는 모듈의 의존 패키지를 모두 넣어야 합니다. 여기서는 messaging, auth, firestore, functions가 필요합니다. 각 모듈의 버전을 주의하셔야 합니다. 서로 의존관계가 있어서 버전이 다르면 제대로 동작하지 않을 수 있습니다. 버전 관련해서 react-native-firebase의 문서를 참고하세요.
https://rnfirebase.io/docs/v5.x.x/getting-started

dependencies {
    implementation project(':react-native-firebase')

    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
    implementation "com.facebook.react:react-native:+"  // From node_modules
    implementation "com.google.android.gms:play-services-base:16.1.0"
    implementation 'com.google.firebase:firebase-core:16.0.9'
    implementation "com.google.firebase:firebase-messaging:18.0.0"
    implementation "com.google.firebase:firebase-auth:17.0.0"
    implementation "com.google.firebase:firebase-firestore:19.0.0"
    implementation "com.google.firebase:firebase-functions:17.0.0"
}

MainApplication.java 파일

아래와 같이 필요한 모듈 내용을 포함시킵니다.

import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
import io.invertase.firebase.auth.RNFirebaseAuthPackage;
import io.invertase.firebase.firestore.RNFirebaseFirestorePackage;
import io.invertase.firebase.functions.RNFirebaseFunctionsPackage;
import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage;

(생략)
public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        new RNFirebasePackage(),
        new RNFirebaseMessagingPackage(),
        new RNFirebaseAuthPackage(),
        new RNFirebaseFirestorePackage(),
        new RNFirebaseFunctionsPackage(),
        new RNFirebaseNotificationsPackage()
      );
    }
(생략)

AntroidManifest.xml 파일

아래와 같이 메시지 관련된 권한, 기능을 설정합니다.

(생략)
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
<application>
(생략)
        <service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
        <service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />
(생략)
</application>
</manifest>

Android Studio에서 Build -> Make Project를 클릭하여 프로젝트 빌드를 합니다. 문제가 없다면 이제 React Native 코딩을 할 차례입니다.

코딩은 다음편에서 진행하겠습니다.

Coin Marketplace

STEEM 0.26
TRX 0.11
JST 0.033
BTC 64207.05
ETH 3065.15
USDT 1.00
SBD 3.87