如何从 Future 函数返回这个布尔值?

问题描述 投票:0回答:1

我有一个函数正在监听文档中的更改以确定用户是在线还是离线,但我无法返回布尔值并且默认值始终返回为 false,我想存储该值到一个变量中,我可以在用户界面中使用该变量来显示用户是在线还是离线。代码如下:

Future<bool> checkUserOnlineStatus({
    required String userId,
  }) async {
    bool isUserOnline = false;
    DocumentReference documentReference =
        firestore.collection('users').doc(userId);

    documentReference.snapshots().listen((event) async {
      isUserOnline = await event.get('isOnline');
      // this prints perfectly fine ...
      isUserOnline ? print("user is online") : print("user is offline");
    });

    return isUserOnline;
    // but here the value is always returned as false ...
  }

此函数在 Stream 中被调用,因此我可以跟踪文档中的更改,并立即将更改反映到用户界面上。我真的不明白我的实现的哪一部分有缺陷,导致无法将 isOnline 状态获取到小部件中。

PreferredSizeWidget chatScreenAppBar() {
    bool isUserOnline = false;
    return AppBar(
      leading: IconButton(
        onPressed: () {
          Navigator.pop(context);
        },
        icon: const Icon(
          Icons.chevron_left_rounded,
          size: 36,
        ),
      ),
      title: StreamBuilder(
        stream: Stream.fromFuture(
          Future(() async {
            isUserOnline = await checkUserOnlineStatus(
              userId: widget.userData['userId'],
            );
          }),
        ),
        builder: (context, snapshot) {
          return Row(
            children: [
              ClipRRect(
                borderRadius: BorderRadius.circular(30),
                child: Image.network(
                  widget.userData['profileImage'],
                  height: 50,
                  width: 50,
                  fit: BoxFit.cover,
                ),
              ),
              Padding(
                padding: const EdgeInsets.only(left: 10),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Padding(
                      padding: const EdgeInsets.only(bottom: 5),
                      child: Text(
                        widget.userData['username'],
                        style: const TextStyle(
                          fontSize: 16,
                          fontWeight: FontWeight.w600,
                        ),
                      ),
                    ),
                    Row(
                      children: [
                        CircleAvatar(
                          radius: 3.5,
                          backgroundColor: isOnline
                              ? Colors.greenAccent[700]
                              : Colors.grey[400],
                        ),
                        Padding(
                          padding: const EdgeInsets.only(left: 4),
                          child: Text(
                            isOnline ? "Online" : "Offline",
                            style: TextStyle(
                              fontSize: 11,
                              color: widget.userData['isOnline']
                                  ? Colors.greenAccent[700]
                                  : Colors.grey[400],
                            ),
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ],
          );
        },
      ),
      actions: [
        IconButton(
          onPressed: () {},
          icon: const Icon(
            Icons.menu_rounded,
            size: 30,
          ),
        ),
      ],
    );
  }

预先感谢您的帮助!

flutter stream future
1个回答
0
投票

试试这个:

import 'dart:async';

Future<bool> checkUserOnlineStatus({
  required String userId,
}) async {
  Completer<bool> completer = Completer<bool>();
  
  DocumentReference documentReference =
      firestore.collection('users').doc(userId);

  documentReference.snapshots().listen((event) async {
    bool isUserOnline = await event.get('isOnline');
    // This prints perfectly fine ...
    isUserOnline ? print("user is online") : print("user is offline");
    
    // Complete the Future with the updated value
    completer.complete(isUserOnline);
  });

  return completer.future;
}
© www.soinside.com 2019 - 2024. All rights reserved.