gpt4 book ai didi

firebase - FCM 到多个设备( token )列表

转载 作者:行者123 更新时间:2023-12-04 16:03:27 34 4
gpt4 key购买 nike

我的目标是使用 flutter 将 FCM 消息发送到包含在文档映射中的多个 token 。当前代码使用“全部发送”功能,并按预期发送给所有人。我希望插入一个widget.document.[token] 或类似的引用将只发送到文档/列表中包含的所有项目。
Firebase uses sendAll to send to specific devices so I was hoping this would work.

  • 使用文档( token )引用不会返回错误,但也不会返回消息
  • 使用仅包含 token 的快照会返回一个错误,该错误仅
    可以传递静态项,还有一些语法问题
  • 使用 api/http 返回错误 posturl 返回 null

  • 除了尝试上述方法外,我还研究了其他人尝试过的方法。
  • functions/index.ts, this is designed for mulitple tokens for single user
  • push list programmatically yielded some syntax errors, and post url null

  • 以下是我的一些错误:
  • 尝试调用:
  • [错误:flutter/lib/ui/ui_dart_state.cc(157)] 未处理的异常:NoSuchMethodError:在 null 上调用了方法“[]”。
  • 尝试调用:post("https://fcm.googleapis.com/fcm/send ", body: "{\"token\":null,

  • 这是我的数据库结构的图片:

    Firebase Database Structure

    最后,这是我的代码:
    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}'),
    ));
    }
    }
    }

    当然,提前感谢大家的时间。

    最佳答案

  • 您的 firestore 实例返回用户文档列表。您需要遍历文档以仅提取文档中的标记并将它们放入字符串列表中,然后将其传递给 FCM。

  • 如果您比较您的屏幕截图和应该返回文档的代码。他们不对齐。你可以改变它。
    //                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 字段中。
  • 您尚未将 token 传递到实际的异步函数 Messaging.sendToAll

    最终响应 = 等待 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/

    34 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com