Flutter:如何使用 fcm 以编程方式发送推送通知
Posted
技术标签:
【中文标题】Flutter:如何使用 fcm 以编程方式发送推送通知【英文标题】:Flutter: How can i send push notification programmatically with fcm 【发布时间】:2019-06-20 03:52:09 【问题描述】:我正在创建一个聊天应用程序,如果此人有新消息,我想使用 fcm 发送通知,但我不知道如何继续。我发现的所有教程都用于从 firebase 发送消息。但是我想在有新消息给这个人时自动发送它
【问题讨论】:
***.com/questions/37371990/… 还有Dart package 也可以发送通知。 如何用颤振发送这个? DATA='"notification": "body": "this is a body","title": "this is a title", "priority": "high", "data": "click_action": " FLUTTER_NOTIFICATION_CLICK", "id": "1", "status": "done", "to": "我将在这里列出一些我参与的相关问题并提供答案。我想您会发现很多有关在聊天应用中使用 Firebase 云消息传递 (FCM) 的相关信息。
-
Is FCM the only way to build a chat app ?
Suggested approach to use FCM in a chat app
Is using topics a better solution then using the fcmToken in a chat app?
Problems with FCM onMessage while app is in background
Problem: after logoff, user continues to receive notifications
祝你好运!
【讨论】:
【参考方案2】:如果您使用 firebase,可能的解决方法应该是这样的:
您需要为特定用户存储每个 Firebase FCM 令牌(此处需要考虑到用户可以从多个设备同时登录其帐户),以便您可以存储 userId em> 和他的 deviceUniqueId on flutter 你可以从 device_info https://pub.dev/packages/device_info 获得它:
String identifier;
final DeviceInfoPlugin deviceInfoPlugin = new DeviceInfoPlugin();
try
if (Platform.isandroid)
var build = await deviceInfoPlugin.androidInfo;
identifier = build.id.toString();
else if (Platform.isios)
var data = await deviceInfoPlugin.iosInfo;
identifier = data.identifierForVendor;//UUID for iOS
on PlatformException
print('Failed to get platform version');
然后要获取 Firebase 为每个设备提供的唯一 CFM 令牌,您可以使用 Firebase firebase_messaging 插件 (https://pub.dev/packages/firebase_messaging) getToken() 获取它并将令牌插入到 Firestore(或您要存储它的其他数据库)
FirebaseMessaging firebaseMessaging = new FirebaseMessaging();
firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, badge: true, alert: true));
firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings)
print("Settings registered: $settings");
);
firebaseMessaging.getToken().then((token)
print('--- Firebase toke here ---');
Firestore.instance.collection(constant.userID).document(identifier).setData( 'token': token);
print(token);
);
之后,您可以为一个用户插入一个或多个连接到多个设备的 FCM 令牌。 1 个用户……n 个设备,1 个设备……1 个唯一令牌,用于从 Firebase 获取推送通知。
当有新消息发送给该人时自动发送:现在您需要调用 Firestore API(确实非常快,但需要注意您在此处使用的计划限制) 或另一个 API 调用(如果您将令牌存储到另一个数据库),以便为每个用户获取令牌/令牌并发送推送通知。
要从 Flutter 发送推送通知,您可以使用 Future 异步函数。 Ps:我在这里传递一个 List 作为参数,以便使用 "registration_ids" 而不是 "to" 并将推送通知发送到多个令牌,如果用户已经在多个设备上登录。
Future<bool> callOnFcmApiSendPushNotifications(List <String> userToken) async
final postUrl = 'https://fcm.googleapis.com/fcm/send';
final data =
"registration_ids" : userToken,
"collapse_key" : "type_a",
"notification" :
"title": 'NewTextTitle',
"body" : 'NewTextBody',
;
final headers =
'content-type': 'application/json',
'Authorization': constant.firebaseTokenAPIFCM // 'key=YOUR_SERVER_KEY'
;
final response = await http.post(postUrl,
body: json.encode(data),
encoding: Encoding.getByName('utf-8'),
headers: headers);
if (response.statusCode == 200)
// on success do sth
print('test ok push CFM');
return true;
else
print(' CFM error');
// on failure do sth
return false;
您还可以检查邮递员的邮递电话以进行一些测试。 POST 请求 在标题上添加:
-
key 授权 value key=AAAAO........ // 项目概览 -> 云消息传递 -> 服务器密钥
key Content-Type with value application/json
并在正文上添加
"registration_ids" :[ "userUniqueToken1", "userUniqueToken2",... ],
"collapse_key" : "type_a",
"notification" :
"body" : "Test post",
"title": "Push notifications E"
"registration_ids" 将其发送到多个令牌(同一用户同时登录多个设备) “to” 以便将其发送到单个令牌(每个用户一个设备/或始终更新与他的设备连接的用户令牌并具有 1 个令牌...1 个用户)
我正在对响应进行编辑,以便在受信任的环境或服务器上添加FCM 服务器密钥非常重要!
【讨论】:
firebaser here 在客户端代码中使用"key=your_server_key"
是一个严重的安全风险,因为它允许恶意用户向您的用户发送他们想要的任何消息。这是一种不好的做法,不应在生产级应用程序中使用。如需更好的方法,请参阅fireship.io/lessons/flutter-push-notifications-fcm-guide 和我的答案:***.com/a/57842615
是的,这个也是为了开发目的,就像上面的邮递员示例一样,我正在编辑答案,因为我也在服务器上设置了服务器密钥,当调用 API 时!跨度>
我们如何做到这一点'这里需要考虑到用户可以从多个设备同时登录他的帐户'
当您可以保存需要使用的元数据但确实可以使用另一个数据库时,我以使用 Cloud Firestore 为例。您可以在 Collection 上保存用户 ID,在每个 Document 上使用 device_info pub.dev/packages/device_info 在 Flutter 上的每个设备中唯一的设备 ID,您可以非常简单地获得该信息在 Collection 上,您可以存储 Firebase 令牌,以便在该设备上发送推送通知。这样,1 次使用可以有多个设备,每个设备将有一个令牌。抱歉迟到了
我的 firebase 项目中目前有 2 个 android 应用,如何指定通知与哪个应用相关?【参考方案3】:
//Notification Sending Side Using Dio flutter Library to make http post request
static Future<void> sendNotification(receiver,msg)async
var token = await getToken(receiver);
print('token : $token');
final data =
"notification": "body": "Accept Ride Request", "title": "This is Ride Request",
"priority": "high",
"data":
"click_action": "FLUTTER_NOTIFICATION_CLICK",
"id": "1",
"status": "done"
,
"to": "$token"
;
final headers =
'content-type': 'application/json',
'Authorization': 'key=AAAAY2mZqb4:APA91bH38d3b4mgc4YpVJ0eBgDez1jxEzCNTq1Re6sJQNZ2OJvyvlZJYx7ZASIrAj1DnSfVJL-29qsyPX6u8MyakmzlY-MRZeXOodkIdYoWgwvPVhNhJmfrTC6ZC2wG7lcmgXElA6E09'
;
BaseOptions options = new BaseOptions(
connectTimeout: 5000,
receiveTimeout: 3000,
headers: headers,
);
try
final response = await Dio(options).post(postUrl,
data: data);
if (response.statusCode == 200)
Fluttertoast.showToast(msg: 'Request Sent To Driver');
else
print('notification sending failed');
// on failure do sth
catch(e)
print('exception $e');
static Future<String> getToken(userId)async
final Firestore _db = Firestore.instance;
var token;
await _db.collection('users')
.document(userId)
.collection('tokens').getDocuments().then((snapshot)
snapshot.documents.forEach((doc)
token = doc.documentID;
);
);
return token;
//Now Receiving End
class _LoginPageState extends State<LoginPage>
with SingleTickerProviderStateMixin
final Firestore _db = Firestore.instance;
final FirebaseMessaging _fcm = FirebaseMessaging();
StreamSubscription iosSubscription;
//this code will go inside intiState function
if (Platform.isIOS)
iosSubscription = _fcm.onIosSettingsRegistered.listen((data)
// save the token OR subscribe to a topic here
);
_fcm.requestNotificationPermissions(IosNotificationSettings());
_fcm.configure(
onMessage: (Map<String, dynamic> message) async
print("onMessage: $message");
showDialog(
context: context,
builder: (context) => AlertDialog(
content: ListTile(
title: Text(message['notification']['title']),
subtitle: Text(message['notification']['body']),
),
actions: <Widget>[
FlatButton(
child: Text('Ok'),
onPressed: () => Navigator.of(context).pop(),
),
],
),
);
,
onLaunch: (Map<String, dynamic> message) async
print("onLaunch: $message");
// TODO optional
,
onResume: (Map<String, dynamic> message) async
print("onResume: $message");
// TODO optional
,
);
//saving token while signing in or signing up
_saveDeviceToken(uid) async
// FirebaseUser user = await _auth.currentUser();
// Get the token for this device
String fcmToken = await _fcm.getToken();
// Save it to Firestore
if (fcmToken != null)
var tokens = _db
.collection('users')
.document(uid)
.collection('tokens')
.document(fcmToken);
await tokens.setData(
'token': fcmToken,
'createdAt': FieldValue.serverTimestamp(), // optional
'platform': Platform.operatingSystem // optional
);
【讨论】:
你的答案背景我理解,但代码不清楚。您使用了哪些 Firebase 组件。如果您可以在此页面中添加包含的文件并且还想知道您为什么使用 DIO 插件,那就更好了。以上是关于Flutter:如何使用 fcm 以编程方式发送推送通知的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 FCM 和 Flutter(一个到另一个设备)发送推送通知?
Flutter FCM:在数据消息中发送documentSnapshot
currentuser 如何在flutter中通过fcm向另一个用户发送请求通知?