我的目标是使用 flutter 将 FCM 消息发送到包含在文档映射中的多个 token 。当前代码使用“全部发送”功能,并按预期发送给所有人。我希望插入一个widget.document.[token] 或类似的引用将只发送到文档/列表中包含的所有项目。
Firebase uses sendAll to send to specific devices so I was hoping this would work.
可以传递静态项,还有一些语法问题
除了尝试上述方法外,我还研究了其他人尝试过的方法。
以下是我的一些错误:
这是我的数据库结构的图片:
最后,这是我的代码:
import 'package:chat/screens2/alert_widget.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:geo_firestore/geo_firestore.dart';
import 'package:geolocator/geolocator.dart';
import 'package:chat/api/messaging.dart';
import 'package:chat/models/messages.dart';
import 'package:flutter/widgets.dart';
class SendAlert extends StatefulWidget {
static const String id = 'send_alert';
final Message message;
final url;
final body;
final title;
final image;
final content;
SendAlert({
Key key,
this.title,
this.url,
this.body,
this.message,
this.image,
this.content,
String alertIdd,
}) : super(key: key);
get documents => null;
SendAlertState createState() => SendAlertState();
}
Firestore firestore = Firestore.instance;
GeoFirestore geoFirestore = GeoFirestore(firestore.collection('users'));
class SendAlertState extends State<SendAlert> {
FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
TextEditingController roomnameController = TextEditingController();
final TextEditingController titleController = TextEditingController();
final TextEditingController bodyController = TextEditingController();
final List<Message> messages = [];
TextEditingController citystateController = TextEditingController();
final db = Firestore.instance;
get title => null;
get body => null;
get uid => null;
get alertidd => null;
var currentLocation;
var clients = [];
List<Map<String, dynamic>> _documents;
void onBbackPressed(BuildContext context) => Navigator.pop(context);
@override
void initState() {
super.initState();
populateClientu();
Geolocator().getCurrentPosition().then((currloc) {
setState(() {
currentLocation = currloc;
});
});
_firebaseMessaging.onTokenRefresh.listen(sendTokenToServer);
_firebaseMessaging.getToken();
_firebaseMessaging.subscribeToTopic('all');
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
final notification = message['notification'];
setState(() {
messages.add(Message(
title: notification['title'], body: notification['body']));
});
},
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
final notification = message['data'];
setState(() {
messages.add(Message(
title: '${notification['title']}',
body: '${notification['body']}',
));
});
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, badge: true, alert: true));
}
populateClientu() async {
Position position = await Geolocator()
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
var queryLocation = GeoPoint(position.latitude, position.longitude);
List<DocumentSnapshot> snapshots =
await geoFirestore.getAtLocation(queryLocation, 10.0);
final documents = snapshots.map((doc) {
return doc.data;
}).toList();
setState(() {
_documents = documents;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromARGB(255, 4, 22, 36),
title: Text('SEND MSG'),
leading: IconButton(
onPressed: () => this.onBbackPressed(context),
icon: Icon(Icons.arrow_back),
),
),
backgroundColor: Color.fromARGB(255, 4, 22, 36),
body:
Container(
width: 250,
height: 35,
margin: EdgeInsets.only(top: 4),
child: Opacity(
opacity: 0.8,
child: FlatButton(
color: Color.fromARGB(51, 255, 255, 255),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
side: BorderSide(
width: 0.75,
color: Color.fromARGB(255, 255, 255, 255),
style: BorderStyle.solid,
),
),
textColor: Color.fromARGB(255, 255, 255, 255),
padding: EdgeInsets.all(0),
child: Text(
"SEND ALERT",
style: TextStyle(
fontSize: 12,
letterSpacing: 2,
fontFamily: "Roboto",
fontWeight: FontWeight.w500,
),
textAlign: TextAlign.left,
),
onPressed: () async {
// const querySnapshot = await db <--- I suspect the document map has extra unused data. I thought maybe FCM will only accept and array of tokens, this did not work either.
// .collection('users')
// .document()
// .collection('token')
// .get();
sendNotification();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AlertWidget()));
})))
);
}
void sendTokenToServer(String fcmToken) {
print('Token: $fcmToken');
}
Future sendNotification() async {
//Future sendNotification(documents(token)) async { <--- I tried to pass widget.document[token]
final response = await Messaging.sendToAll(
title: titleController.text,
body: bodyController.text,
);
if (response.statusCode != 200) {
Scaffold.of(context).showSnackBar(SnackBar(
content:
Text('[${response.statusCode}] Error message: ${response.body}'),
));
}
}
}
当然,提前感谢大家的时间。
最佳答案
如果您比较您的屏幕截图和应该返回文档的代码。他们不对齐。你可以改变它。
// const querySnapshot = await db <--- I suspect the document map has extra unused data. I thought maybe FCM will only accept and array of tokens, this did not work either.
// .collection('users')
// .document()
// .collection('token')
// .get();
到
// const querySnapshot = await db <--- I suspect the document map has extra unused data. I thought maybe FCM will only accept and array of tokens, this did not work either.
// .collection('users')
// .document("DOCUMENT ID")
// .get();
以上将得到一个文件。然后,您可以映射文档并获取单个 token ,您可以将其传递到 Message 组件的 token 字段中。
最终响应 = 等待 Messaging.sendToAll(
标题:titleController.text,
正文:bodyController.text,
);
上面应该在正文中包含一个 token 字符串,如下所示。
final response = await Messaging.sendToAll(
title: titleController.text,
body: bodyController.text,
token:fcmTokenReturnedFromFirestore
);
关于firebase - FCM 到多个设备( token )列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59733469/