【问题标题】:Flutter - widget variables are always nullFlutter - 小部件变量始终为空
【发布时间】:2021-07-07 19:58:41
【问题描述】:

我有一个连接到 firebase 的 Flutter 应用,我正在使用它来接收来自 Firebase Cloud Messaging 的推送通知,使用此代码。每当我调用变量widget.titlewidget.body 时,它们都是空的,但是当方法收到通知时,它们具有来自 FCM 的值。我该怎么办?

class PushList extends StatefulWidget {
  
  Map<dynamic, dynamic> notific;
  String title, body;

  Future<dynamic> fcmMessageReceiver() async {
    FirebaseMessaging.instance.getInitialMessage().then((value) {
      if (value != null) {}
    });

    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      if (message.notification != null) {
        notificacao = {
          'title': message.notification.title,
          'body': message.notification.body
        };
        title = message.notification.title;
        body = message.notification.body;

        print('MENSAGEM: $notific');
      }
    });
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {});
  }

  PushList() {
  }

  @override
  _PushListState createState() => _PushListState();
}

class _PushListState extends State<PushList> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBody: true,
      backgroundColor: Colors.white,
      appBar: null,
      body: ListView(
        children: [
          widget.notific != null
              ? Card(
                  margin: EdgeInsets.all(10),
                  elevation: 4,
                  child: ListTile(
                    title: Text(
                      widget.title,
                    ),
                    subtitle: Text(
                      widget.body,
                    ),
                  ),
                )
              : Container(
                  child: Text("U don't have new notifcs."),
                ),
        ],
      ),
    );
  }
}

【问题讨论】:

    标签: firebase flutter dart firebase-cloud-messaging


    【解决方案1】:

    PushList 应该是不可变的。在状态内部定义属性并在initState 内部调用fcmMessageReceiver。另外你需要在设置titlebody后调用setState触发重建:

    class PushList extends StatefulWidget {
      @override
      _PushListState createState() => _PushListState();
    }
    
    class _PushListState extends State<PushList> {
      Map<dynamic, dynamic> notific;
      String title, body;
    
      @override
      void initState() {
        super.initState();
        fcmMessageReceiver();
      }
    
      Future<dynamic> fcmMessageReceiver() async {
        FirebaseMessaging.instance.getInitialMessage().then((value) {
          if (value != null) {}
        });
    
        FirebaseMessaging.onMessage.listen((RemoteMessage message) {
          if (message.notification != null) {
            if (mounted) {
              setState(() {
                notificacao = {
                  'title': message.notification.title,
                  'body': message.notification.body
                };
                title = message.notification.title;
                body = message.notification.body;
              });
            }
            print('MENSAGEM: $notific');
          }
        });
        FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {});
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          extendBody: true,
          backgroundColor: Colors.white,
          appBar: null,
          body: ListView(
            children: [
              notific != null
                  ? Card(
                      margin: EdgeInsets.all(10),
                      elevation: 4,
                      child: ListTile(
                        title: Text(
                          title ?? '',
                        ),
                        subtitle: Text(
                          body ?? '',
                        ),
                      ),
                    )
                  : Container(
                      child: Text("U don't have new notifcs."),
                    ),
            ],
          ),
        );
      }
    }
    

    【讨论】:

    • 我该如何调用这个方法?因为它需要是一个initState,并且State类被标记为私有。应该是这样的:PushList().createState().fcmMessageReceiver();
    • 为什么需要从父部件调用?在颤振中,这不是您应该使用小部件的方式。您不会继续引用小部件并调用内容。但是,如果您真的想这样做,请执行以下操作: 1. 将 _PushListState 重命名为 PushListState 2. 从父小部件创建全局键 final key = new GlobalKey&lt;PushListState&gt;(); 3. 将其传递给 PushList(key: key), 4 。父调用方法:key.currentState.fcmMessageReceiver();
    • PushList 类不是我的主类。如果在 initState 中没有调用 firebase 方法,它将不会收到通知。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 2021-05-05
    • 1970-01-01
    • 2017-03-12
    • 2021-12-22
    相关资源
    最近更新 更多