当一个用户按下按钮时,我如何向另一个用户发送通知?能否有人展示一段代码片段?请注意,之前已经有人问过这个问题,但因为有“多个答案”,所以被关闭了。提供的相似链接没有解释在 Flutter 中如何发送通知。
我已经找到了如何使用应用内功能向另一个设备发送通知的方法。
首先,您需要导入必要的包:
firebase_messaging
flutter_local_notifications
注意:您还将使用http
包
还要注意:要向另一个设备发送通知,您必须知道该设备的设备令牌。我建议获取令牌并将其保存在Firestore或实时数据库中。以下是获取设备令牌的代码。
String? mtoken = " ";
void getToken() async {
await FirebaseMessaging.instance.getToken().then((token) {
setState(() {
mtoken = token;
});
});
}
令牌将保存在mtoken中,您现在可以将其用作接下来步骤的令牌。
在我的functions
文件夹中,我在index.js
中添加了此代码
/* eslint-disable */
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.sendNotification = functions.https.onCall(async (data, context) => {
await admin.messaging().sendMulticast({
tokens: data.tokens,
notification: {
title: data.title,
body: data.body,
imageUrl: data.imageUrl,
},
});
您可以使用以下代码在Flutter应用程序中调用此函数
Future<void> sendNotification(
tokens,
String title,
String body,
String imageUrl,
) async {
FirebaseFunctions functions =
FirebaseFunctions.instanceFor(region: 'us-central1');
try {
final HttpsCallable callable = functions.httpsCallable('sendNotification');
final response = await callable.call({
'tokens': tokens,
'title': title,
'body': body,
'imageUrl': imageUrl,
});
print('Message sent: ${response.data}');
} catch (e) {
print('Error sending message: $e');
}
}
下一步是请求发送推送通知到您的应用程序的权限。
void requestPermission() async {
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
print('User granted permission');
} else if (settings.authorizationStatus ==
AuthorizationStatus.provisional) {
print('User granted provisional permission');
} else {
print('User declined or has not accepted permission');
}
}
如果您在控制台中收到“用户已拒绝或未接受权限”的消息,请尝试退出应用程序,找到主屏幕上的图标,按住应用程序图标,点击“应用信息”,点击“通知”并打开“所有[应用名称]通知”。
您还需要两个函数来加载Firebase Cloud Messaging通知以及一个监听通知的函数。
加载Firebase Cloud Messaging通知的代码:
void loadFCM() async {
if (!kIsWeb) {
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
importance: Importance.high,
enableVibration: true,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
/// Create an Android Notification Channel.
///
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
/// Update the iOS foreground notification presentation options to allow
/// heads up notifications.
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
}
}
同时,这个函数用来监听 Firebase Cloud Messaging 通知。
void listenFCM() async {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
// TODO add a proper drawable resource to android, for now using
// one that already exists in example app.
icon: 'launch_background',
),
),
);
}
});
}
在页面初始化时,您需要运行loadFCM、listenFCM和requestPermission。
void initState() {
super.initState();
requestPermission();
loadFCM();
listenFCM();
}
下一步是找到您的Firebase Cloud Messaging
API密钥。这可以通过前往Firebase项目>项目设置>云消息传递来完成,然后在Cloud Messaging API(Legacy)
下复制API密钥即可。
当您拥有Firebase Cloud Messaging API密钥时,这是显示通知的代码,给定通知标题、正文和设备令牌以将其发送到。
void sendPushMessage(String body, String title, String token) async {
try {
await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{
'Content-Type': 'application/json',
'Authorization':
'key=REPLACETHISWITHYOURAPIKEY',
},
body: jsonEncode(
<String, dynamic>{
'notification': <String, dynamic>{
'body': body,
'title': title,
},
'priority': 'high',
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done'
},
"to": token,
},
),
);
print('done');
} catch (e) {
print("error push notification");
}
}
现在你可以像这样调用这个函数:
sendPushMessage('通知正文', '通知标题', '替换为设备令牌');
希望这能帮到你。
您需要使用Firebase云消息传递(Firebase Cloud Messaging)。
我所采用的方法是使用Cloud Function,您可以通过HTTP甚至Firestore触发器来触发它,如下所示:
// The Firebase Admin SDK to access Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
/**
* Triggered by a change to a Firestore document.
*
* @param {!Object} event Event payload.
* @param {!Object} context Metadata for the event.
*/
exports.messageNotificationTrigger = (change, context) => {
db.collection('users').get().then((snapshot) => {
snapshot.docs.forEach(doc => {
const userData = doc.data();
if (userData.id == '<YOUR_USER_ID>') {
admin.messaging().sendToDevice(userData.deviceToken, {
notification: {
title: 'Notification title', body: 'Notification Body'}
});
}
});
});
};
在您的用户集合中注册的每个用户都必须具有从其访问应用程序的设备发送的设备令牌。
从Flutter,使用FCM包,这是将设备令牌发送到Firebase的方法:
// fetch the device token from the Firebase Messaging instance
// and store it securely on Firebase associated with this user uid
FirebaseMessaging.instance.getToken().then((token) {
FirebaseFirestore.instance.collection('users').doc(userCreds.user!.uid).set({
'deviceToken': token
});
});
userCredentials.user!.uid 是使用 Firebase Authentication 登录应用程序时使用的用户,如下所示:
UserCredential userCreds = await FirebaseAuth.instance.signInWithCredential(credential);