文章大綱
在react native中的通知有分兩種,一種是本地通知(自己寫按鈕就可以觸發通知),一種是遠程通知。
遠程通知需要一個firebase帳號,並且創建firebase專案,這部分之後再更新(茶
因為新公司只有提供windows電腦,所以本篇只示範android平台的local通知…QQ
安裝步驟可以參考這裡,但是你懶得看,所以我寫了這篇。
安裝
$ yarn add react-native-push-notification
// or
$ npm install --save react-native-push-notification
修改android/app/arc/main/AndroidManifest.xml
<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 -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground"
android:value="false"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
android:resource="@color/white"/>
<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>
可以看到夾在notification註解中的那些都是我新增的。
在android/app/src/main/res/values 新增一個檔案叫做 colors.xml
貼上以下程式碼,如果通知的視窗想改顏色就是從這裡改。
<resources>
<color name="white">#FFF</color>
</resources>
到目前為止就安裝完了。
接下來就可以開始寫code啦!
在utils/新增一個檔案叫做NotifService.js
你也可以新增在其他地方,反正找得到就好,建議是工具類都放在自己一個資料夾。
引入套件 :
import { Platform } from 'react-native';
import PushNotification from 'react-native-push-notification';
設定config :
PushNotification.configure({
popInitialNotification: true,
requestPermissions: Platform.OS === 'ios' // 因為我是local通知,所以他官網叫我這樣寫。
});
輸出方法 :
會用到3種方法 — 創建channel、查詢channel是否存在、推送local通知,另外你可能會有一些給你測試用的方法像是 : 查詢所有channels、delete channel…
export default {
getChannelExists(channelId) {
//....
},
createChannel(channelId) {
//...
},
localNotif(channelId) {
//...
}
}
最下面會補充完整
NotifService.js
內的寫法,其實就是官網整個貼過來,然後刪掉option那些沒用到的部分。
接著在頁面中引用 :
import NotifService from '@/utils/NotifService';
如果要推送通知,必須要先有至少一個channel
,每個channel都會要給他一個channelId
,送出通知的時候,要指定是要送到哪個channel
才能成功收到,所以也就是說你可以有很多個channel
推送不同分類的通知,跟socket
訂閱頻道有點像。
假設我這邊要接收通知的類型是訂單,channelId
就可以假設為 'orderChannel'
。
以下程式碼是先判斷你是否已經有 id
叫做 'orderChannel'
的channel
,沒有的話就創建一個。
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]);
const pushOrderNotif = () => {
NotifService.localNotif('orderChannel');
};
pushOrderNotif(); // 你可以把方法綁定在按鈕上測試
以下是完整程式碼 :
import { Platform } from 'react-native';
import PushNotification from 'react-native-push-notification';
PushNotification.configure({
popInitialNotification: true,
requestPermissions: Platform.OS === 'ios'
});
export default {
deleteChannel(channelId) {
PushNotification.deleteChannel(channelId);
},
getChannelExists(channelId) {
return new Promise((resolve, reject) => {
PushNotification.channelExists(channelId, function (exists) {
resolve(exists);
});
});
},
getChannels() {
return new Promise((resolve, reject) => {
PushNotification.getChannels(function (channels) {
resolve(channels);
});
});
},
createChannel(channelId) {
PushNotification.createChannel(
{
channelId: channelId,
channelName: channelId
},
created => console.log(`createChannel ${channelId} returned '${created}'`)
);
},
localNotif(channelId) {
PushNotification.localNotification({
channelId: channelId,
autoCancel: true,
bigText: '有新訂單!',
subText: '租車管理新訂單通知',
actions: ['ok'],
message: 'new order notif' // (required)
});
}
};
import React, {
useEffect,
useState
} from 'react';
import NotifService from '@/utils/NotifService';
const Home = () => {
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]);
const pushOrderNotif = () => {
NotifService.localNotif('orderChannel');
};
return (<button onPress={pushOrderNotif}>發送通知</button>);
}
發表評論
想要加入討論嗎?請盡情發表您的想法!