为什么此流生成器在不重新启动应用的情况下不显示数据?



我正试图让Flutter项目显示从Firebase实时数据库返回的项目的简单列表。代码基本上有效,但每次注销并以不同用户身份重新登录时,我都必须重新启动应用程序,这不是我想要的。我需要用户登录时显示他们的数据。我不太明白这里发生了什么(经过几天的反复尝试和谷歌搜索,我偶然发现了一个功能性解决方案(,但我认为Stream或多或少是来自特定来源的"实时"数据流。

EDIT:kPAYEES_NODE是存储在其他地方的常量,在RTDB:中解析为"users/uid/payees">

import 'package:firebase_database/firebase_database.dart';
import 'auth_service.dart';
final DatabaseReference kUSER_NODE =
FirebaseDatabase.instance.ref('users/${AuthService.getUid()}');
final DatabaseReference kPAYEES_NODE = kUSER_NODE.child('payees');

这是有问题的代码:

class DashboardPage extends StatelessWidget {
const DashboardPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(...),
body: StreamBuilder(
stream: kPAYEES_NODE.onValue,
builder: (context, snapshot) {
final payees = <Payee>[];
if (!snapshot.hasData) {
return Center(child: Column(children: const [Text('No Data')]));
} else {
final payeeData =
(snapshot.data!).snapshot.value as Map<Object?, dynamic>;
payeeData.forEach((key, value) {
final dataLast = Map<String, dynamic>.from(value);
final payee = Payee(
id: dataLast['id'],
name: dataLast['name'],
note: dataLast['note'],
);
payees.add(payee);
});
return ListView.builder(
shrinkWrap: true,
itemCount: payees.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(
payees[index].name,
style: const TextStyle(color: Colors.white),
),
subtitle: Text(
payees[index].id,
style: const TextStyle(color: Colors.white),
),
);
});
}
},
),
floatingActionButton: (...),
);
}
}

这是因为您在代码中只获得当前的UID一次,在这里:

FirebaseDatabase.instance.ref('users/${AuthService.getUid()}')

当这一行运行时,AuthService.getUid()只有一个值。相反,每当用户登录或退出应用程序时,都需要重新评估代码。

在用户可以登录和注销的应用程序中,UID值是一个类似于FirebaseAuth.instance.authStateChanges()公开的流,如Firebase获取当前用户的文档中所示。您可以将authStateChanges()返回的流包装在StreamBuilder中,然后在该构建器的内部创建数据库引用,使其对身份验证状态的更改做出响应。

最新更新