## 設定
:::info
[**參考 firebase 官方文件**](https://firebase.google.com/docs/cloud-messaging/flutter/client?hl=zh-tw)
:::
### iOS
#### 在 Xcode 開啟設定
:::info
[**參考教學**](https://medium.com/@prithvi2229/creating-push-notifications-in-swift-ios-beginners-guide-4a9095fe5f75)
:::
1. `Runner` > `Signing & Capabilities` > `+ Capability`

2. 點擊 `Push Notifications` 加入

3. 點擊 `Backgroud Mode` 加入,然後點擊 `Remote Notifications`


#### 上傳您的 APNs 驗證金鑰
:::info
[**參考教學**](https://docs.getui.com/getui/mobile/ios/apns/)
:::
1. 先跟著參考教學申請 APNs
2. 在 Firebase 控制台的項目內,選擇齒輪圖標,選擇項目設置,然後選擇雲端訊息傳遞選項卡。

3. 為您的開發證書、生產證書或兩者選擇「上傳證書」按鈕。至少需要一個。對於每個證書,選擇 .p12 文件,並提供密碼(如果有)。確保此憑證的捆綁包 ID 與您的應用程式的捆綁包 ID 相符。選擇保存。
### android
不用設定
## 使用範例
```javascript
import 'package:firebase_messaging/firebase_messaging.dart';
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print('Handling a background message ${message.messageId}');
}
Future<void> initializeFirebase() async {
// 初始化
await Firebase.initializeApp();
// iOS 請求通知權限許可
if (Platform.isIOS) {
await FirebaseMessaging.instance
.requestPermission(sound: true, badge: true, alert: true);
}
// 前台
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message whilst in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
});
// 後台點擊開啟
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('A new onMessageOpenedApp event was published!');
print('Message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
});
// 後台、離線
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}
Future<void> main() async {
// ...
// 初始化前一定要加這句
WidgetsFlutterBinding.ensureInitialized();
await initializeFirebase();
runApp(const ZcpApp());
}
```
但是 firebase 推送的通知在開啟 App 時,是不會顯示的,所以還要透過其他套件顯示:`flutter_local_notifications`
## `flutter_local_notifications`
:::info
[**參考教學**](https://hackmd.io/@yen2/SyeeSXntc/https%3A%2F%2Fhackmd.io%2FkfPTDa83RgO2ZtgZkLN9Xw)
:::
設定什麼的參考這篇:[**flutter_local_notifications**](/2h-QxN5VQZ2qjxBhYdTiRw)
### 使用範例
```javascript
class LocalNotifications {
int notificationId = 0;
// 創建 FlutterLocalNotificationsPlugin 實例,用於處理本地通知
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
// 初始化本地通知
Future<void> initializeNotifications() async {
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestNotificationsPermission();
// Android 平台的初始化設置
const initializationSettingsAndroid = AndroidInitializationSettings('icon');
// iOS 平台的初始化設置
const DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings();
// 整合所有平台的初始化設置
const InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
// 初始化本地通知插件
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
);
}
// 顯示本地通知
Future<void> showNotification(String title, String body) async {
// 安卓平台的通知設置
const AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails('zcp', 'zcp',
playSound: true,
priority: Priority.high,
importance: Importance.max);
// iOS 平台的通知設置
const DarwinNotificationDetails iOSPlatformChannelSpecifics =
DarwinNotificationDetails();
const NotificationDetails notificationDetails = NotificationDetails(
android: androidNotificationDetails,
iOS: iOSPlatformChannelSpecifics,
);
await flutterLocalNotificationsPlugin.show(
notificationId, title, body, notificationDetails);
notificationId++;
}
}
```
### 遇到的一些問題
#### android 通知無法顯示
* 解決辦法:記得加上這段
```javascript
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestNotificationsPermission();
```