如何使用 react native + react-native-push-notification + firebase cloud messaging 傳送遠端測試通知到 android emulator

本篇使用的設備跟環境:

  1. windows電腦
  2. 已安裝android studio並且依照RN官網做好設定
  3. npm

要在電腦上的emulator上收到遠端通知,需要準備以下幾件事 :

  1. 創建一個firebase專案
  2. 為firebase專案加入android applications
  3. RN專案安裝react-native-push-notification套件
  4. RN專案設定firebase相關依賴
  5. RN專案訂閱channel
  6. 檢查android emulator是否符合FCM設備要求
  7. 從firebase cloud messaging發送測試通知
  8. 查看是否收到通知

如果你有自己的後端 server(像是 express),似乎你還是需要創建 firebase 專案,差別只在於你可以不用進行第7步驟,其他步驟一樣都是必須的。


創建一個firebase專案

要創建一個firebase專案之前要先註冊,或是你可以直接用google帳號登入。

登入後,進入官網點選「新增專案」

輸入專案名稱,可以自己隨意取。

在這邊我創建了一個專案叫做:RN-notif-demo

完成後按下「繼續」。

是否加入GA? 因為之後要用還是可以加進去,所以我就先把它關掉,然後按「建立專案」

建立專案中,等他跑完~

好了之後就可以按「繼續」


為firebase專案加入android applications

建立好專案之後會進入控制台頁面,因為這邊是示範android,所以點安卓的圖案建立應用程式

如果找不到的話,也可以點左邊的小齒輪,選擇「專案設定」。

在最下面也可以看到應用程式圖案。

1. 註冊應用程式

Android 套件名稱在RN專案中/android/app/src/main/AndroidManifest.xml裡面找到,我先截另一個專案的XDD

填進去之後按下「註冊應用程式」

2. 下載設定檔

點選「下載google-servise.json」把檔案載下來,然後放到你的RN專案/android/內

完整路徑:RN專案/android/google-servise.json

放好之後按「繼續」。

3. 新增firebase SDK

3–1. 進入RN專案/android/build.gradle檔案,新增以下這行:

buildscript {
    ext {
        buildToolsVersion = "29.0.2"
        minSdkVersion = 16
        compileSdkVersion = 29
        targetSdkVersion = 29
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:3.5.3")
        classpath('com.google.gms:google-services:4.3.3') // <-- 新增這一行
    }
}

3–2. 進入RN專案/android/app/build.gradle檔案,新增以下兩行:

apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services' // <-- 先在最上面新增這行

import com.android.build.OutputFile


//...省略



dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    //noinspection GradleDynamicVersion
    implementation "com.facebook.react:react-native:+"  // From node_modules

    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
  
    implementation 'com.google.firebase:firebase-analytics:17.3.0' 
    // 新增上面這行

  	//...省略
    
}

完成之後就按「繼續」。

好的這時候firebase這邊先告一段落,等等再回來firebase網頁,接下來要進入RN專案的設定。


RN專案安裝react-native-push-notification套件

請用vscode打開你的RN專案,並且打開終端機,cd到你的專案路徑。

安裝react-native-push-notification套件

$ npm install --save react-native-push-notification

RN專案設定firebase相關依賴

完整安裝跟環境設定可以參考這裡

進入RN專案/android/app/src/main/AndroidManifest.xml,增加以下設定:(標記在兩個<! — notification — >中間的都是我新增的

  • 兩個<user-permission>,在<manifest>
  • 三個<receiver>,在<application>
  • 一個<service>,在<application>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.transport">

    <uses-permission android:name="android.permission.INTERNET" />
  
    <!-- notification -->
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <!-- notification -->

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme"
      android:usesCleartextTraffic="true">

      <!-- notification -->
      <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" />
      <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
      <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
          <intent-filter>
              <action android:name="android.intent.action.BOOT_COMPLETED" />
              <action android:name="android.intent.action.QUICKBOOT_POWERON" />
              <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
          </intent-filter>
      </receiver>

      <service
          android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
          android:exported="false" >
          <intent-filter>
              <action android:name="com.google.firebase.MESSAGING_EVENT" />
          </intent-filter>
      </service>
      <!-- notification -->

      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>

用紅框框起來比較明顯一點~~~:


RN專案訂閱channel

訂閱通知前,要先寫notification 的底層。

新增一個檔案在RN專案/utils/NotifService.js :

分成三個部分

  1. 引入套件
  2. 設定config
  3. 輸出方法
// 引入套件
import PushNotification from 'react-native-push-notification';

// 設定config
PushNotification.configure({
  popInitialNotification: true,
  requestPermissions: true,
  
  // 使用remote遠端通知的話,一定要先註冊,然後取得token
  onRegister: function (token) {
    console.log('TOKEN:', token);
  },
  onRegistrationError: function (err) {
    console.error(err.message, err);
  }
});

// 輸出方法
export default {
  getChannelExists(channelId) {
    return new Promise((resolve, reject) => {
      PushNotification.channelExists(channelId, function (exists) {
        resolve(exists);
      });
    });
  }
  createChannel(channelId) {
    PushNotification.createChannel(
      {
        channelId: channelId,
        channelName: channelId
      },
      created => console.log(`createChannel ${channelId} returned '${created}'`)
    );
  }
};

使用遠程通知的話,一定要有Regist這個流程,把裝置token傳送到後端,因為後端通知會需要裝置的token才能發送(當然安卓也可以使用topic分類)。
onRegist會在app載入的時候直接註冊然後回傳token

在頁面中引入

useEffect內使用getChannelExists方法檢查某channelId是否已經創建過了,如果沒有就用createChannel創建一個。

import React, {
  useEffect,
  useState
} from 'react';
import NotifService from '@/utils/NotifService';

const App = () => {
  const [notif, setNotif] = useState(null);
  useEffect(() => {
    notif || setNotif(NotifService);
    const asyncFunc = async () => {
      const hasOrderChannel = await notif.getChannelExists('orderChannel');
      hasOrderChannel || notif.createChannel('orderChannel');
    };
    notif && asyncFunc();
  }, [notif]);
}

export default App;

檢查android emulator是否符合FCM設備要求

官網的說明當中有提到,如果你是要用模擬器的朋友,請確保模擬器使用的是有GooglePlay的image,我當初就是漏掉這點,浪費我一天時間在那邊拿不到token。

有圖為證 :

檢查方式:打開Android Studio,點右下角Configure

選ADV Manager,看看你的模擬器有沒有GooglePlay的符號,如果沒有的話請在左下角Create Virtual Device,選一個有Play Store的裝置新增。


從firebase cloud messaging發送測試通知

進入Firebase,在左側選單選擇成長 –> Cloud Messaging,點選畫面中的Send your first message

1. 通知

輸入通知標題通知文字,然後請注意不要選傳送測試訊息!!

因為在這邊我們要把通知送到我們監聽的那個Channel,還有另一個原因是因為,通知送到Channel,有些手機才會跳出通知視窗,否則它只會顯示一個小圖在最上面。

左邊就是使用傳送測試訊息發送的畫面,右邊是發送到Channel的畫面。

輸入好之後請按下一步

2. 指定目標

應用程式下拉選單裡面應該只會有一個App,就是你在前幾步驟設定的。

輸入好之後請按下一步

3. 排定時間

請選擇現在,因為我們是在測試階段,要馬上看到結果才知道自己有沒有成功。

4. 其他選項 (選用)

最重要的一個步驟,在 Android 通知管道 輸入你剛剛在RN專案定義的ChannelID,像是我的例子就是orderChannel

好了之後就案審查

因為我沒有使用GA,所以它會有一排紅字,但不管它,直接按發佈


查看是否收到通知

馬上到你的模擬器去看有沒有收到通知。

應該會看到這種形式的通知,如果沒收到通知,或是過程中有遇到其他錯誤,歡迎留言跟我討論喔 : )

0
0 回復

發表評論

想要加入討論嗎?
請盡情發表您的想法!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。