在上一篇 中,我們完成了:
- 初始化 Firebase 與 Azure Notification Hub
- 成功從 Firebase 取得 FCM token
- 註冊裝置至 Azure Notification Hub(使用 FCM v1 註冊格式)
這篇我們的目標是:
- 如何顯示 前景通知
- 如何 請求 Android 13+ 的通知權限
- 如何處理 通知點擊事件(背景與關閉狀態)
先來認識手機中的 App 通知類型!
App 通知行為分類
App 狀態 |
行為說明 |
顯示位置 |
關閉(not running) |
App 關閉狀態顯示的通知,通知由系統顯示,點擊會啟動 App 並可帶參數 |
通常在手機待機畫面列表,以及運行畫面頂部顯示小圖示 |
背景(background) |
App 在背景模式時顯示,通知由系統顯示,點擊會觸發 onNotificationOpenedApp |
同上 |
前景(foreground) |
App 在畫面上運行時顯示。顯示方法由開發者自行設定。 |
由開發者處理 |
請求 Android 13 通知權限
從 Android 13(API 33)開始,需要向使用者明確請求 POST_NOTIFICATIONS 權限。
1 2 3 4 5 6 7 8 9 10 11
| import { PermissionsAndroid, Platform } from 'react-native'
async function requestAndroidNotificationPermission() { if (Platform.OS === 'android' && Platform.Version >= 33) { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS ) return granted === PermissionsAndroid.RESULTS.GRANTED } return true }
|
顯示前景通知(App 開啟中)
當 App 正在使用中,通知不會由系統自動顯示。我們必須手動接收並彈出提醒。你也可以改用 Toast 或 Modal 呈現。
1 2 3 4 5 6
| import messaging from '@react-native-firebase/messaging' import { Alert } from 'react-native'
messaging().onMessage(async (remoteMessage) => { Alert.alert('前景通知', remoteMessage.notification?.title || '收到通知') })
|
背景狀態通知點擊
1 2 3 4 5 6
| messaging().onNotificationOpenedApp((remoteMessage) => { const messaage = remoteMessage?.data?.messaage if (typeof messaage === 'string') { Alert.alert('來自背景通知訊息:', messaage) } })
|
關閉狀態通知點擊
1 2 3 4 5
| const initialMsg = await messaging().getInitialNotification() const url = initialMsg?.data?.messaage if (typeof messaage === 'string') { Alert.alert('來自關閉通知訊息:', messaage) }
|
完整程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| import { useEffect, useRef, useState } from 'react'; import { StyleSheet, PermissionsAndroid, Platform, Alert } from 'react-native'; import messaging from '@react-native-firebase/messaging'; import registerDeviceToAzure from '@/hooks/useAzureRegistration';
const cleanupFns = useRef<(() => void)[]>([])
export default function HomeScreen() { useEffect(() => { const setupPush = async () => { try { const granted = await requestAndroidNotificationPermission() if (!granted) { Alert.alert('未授權通知權限') return }
const authStatus = await messaging().requestPermission() const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL
if (!enabled) { Alert.alert('FCM 權限未啟用') return }
const token = await messaging().getToken() await registerDeviceToAzure(token)
const unsub1 = messaging().onMessage(async (remoteMessage) => { Alert.alert('前景通知', remoteMessage.notification?.title || '收到通知') })
const unsub2 = messaging().onNotificationOpenedApp((remoteMessage) => { const url = remoteMessage?.data?.url if (typeof url === 'string') { Alert.alert('背景點通知跳轉:', url) } })
const initialMsg = await messaging().getInitialNotification() const url = initialMsg?.data?.url if (typeof url === 'string') { Alert.alert('關閉狀態點通知跳轉:', url) }
cleanupFns.current = [unsub1, unsub2] } catch (err) { Alert.alert('推播初始化錯誤', JSON.stringify(err)) } }
setupPush()
return () => { cleanupFns.current.forEach((unsub) => unsub()) } }, [])
return ( ...略 ); }
|
我們已經完成裝置註冊與 App 端的通知顯示了 🎉
因為我們之前已經有使用 prebuild
生成 android 資料夾,接著只要在終端機執行
1
| ./gradlew assembleRelease
|
打包成功後,release APK 會放在 release 資料夾中
1
| 專案資料夾/android/app/build/outputs/apk/release
|
將 app-release.apk
放進手機完成安裝,就可以使用 Azure 做測試發送囉~
