我已经用 flutter、getx 和 firebase 构建了一个待办事项应用程序。我有一个登录页面、注册页面和待办事项页面,其中显示了待办事项列表。我使用 firebase_auth 包进行身份验证,使用 cloud_firestore 包从 firestore 保存和检索数据。我有 2 个模型 - 一个用于用户,另一个用于待办事项。
为了在 firestore 中保存待办事项,我有以下方法 -
Future<void> addTodo(String content, String uid) async {
try {
await firebaseFirestore
.collection("users")
.doc(uid)
.collection("todos")
.add({
"content": content,
"dateCreated": Timestamp.now(),
"done": false,
});
} catch (e) {
print(e.toString());
rethrow;
}
}
要从 firestore 中检索待办事项列表,我使用以下方法返回待办事项流
Stream<List<TodoModel>> todoStream(String uid) {
return firebaseFirestore
.collection("users")
.doc(uid)
.collection("todos")
.orderBy("dateCreated", descending: true)
.snapshots()
.map((event) {
List<TodoModel> retVal = List.empty(growable: true);
event.docs.forEach((element) {
TodoModel todo = TodoModel();
todo.todoId = element.id;
todo.content = element['content'];
todo.dateCreated = element['dateCreated'];
todo.done = element['done'];
print(todo.toString());
retVal.add(todo);
});
return retVal;
});
}
如您所见,特定用户的待办事项与其 ID 相关联。
现在在我的 todo 控制器的 onInit 方法中,我正在调用上面的函数来获取 todos 流
@override
void onInit() {
String uid = Get.find<AuthController>().user;
todoList.bindStream(DatabaseService().todoStream(uid));
super.onInit();
}
Auth 控制器返回用户的 id,然后将其提供给 todoStream 函数以获取 todos
在构建方法内的应用程序主页中,我像这样注入 Todo 控制器
Get.put(TodoController());
在 Scaffold 小部件的主体中,我像这样使用 Obx 显示待办事项
Obx(
() {
if (Get.find<TodoController>().todos.length > 0) {
return Expanded(
child: ListView.builder(
itemCount: Get.find<TodoController>().todos.length,
itemBuilder: (_, index) {
TodoModel todo = Get.find<TodoController>().todos[index];
return Card(
margin:
EdgeInsets.symmetric(horizontal: 20, vertical: 5),
child: Padding(
padding: EdgeInsets.all(10.0),
child: Row(
children: [
Expanded(
child: Text(
todo.content,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
),
Checkbox(
value: todo.done,
onChanged: (newValue) {
print(newValue);
}),
],
),
),
);
},
),
);
} else {
return Text(
"Loading....",
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
);
}
},
)
我面临的问题是当应用程序启动并且第一个用户登录时,我可以看到 todo 控制器已创建并初始化,并且他的 todos 列表显示在页面上。然而,当他退出并且另一个用户登录页面时,他的名字能够正确显示,这意味着该用户被正确识别,但仍然显示第一个用户的待办事项列表。
这告诉我,当第二个用户登录时,todo控制器的onInit方法没有被调用。
有人知道如何解决这个问题吗?
下面是我的 TodoController -
class TodoController extends GetxController {
Rxn<List<TodoModel>> todoList = Rxn<List<TodoModel>>();
List<TodoModel> get todos => todoList.value ?? [];
void clear() => todoList = Rxn<List<TodoModel>>();
@override
void onInit() {
String uid = Get.find<AuthController>().user;
print("onInit called=====================" + uid);
todoList.bindStream(DatabaseService().todoStream(uid));
print("todo bind stream done=========================");
super.onInit();
}
}
答案 0 :(得分:0)
oninit 函数调用的实际问题是bindstream todoList.bindStream(DatabaseService().todoStream(uid)); 调用此 bindstream 后,它需要一秒钟才能从 firebase 获取数据,然后这将提供给模型,因此您需要在加载数据后在 ui 页面上添加加载程序 todoList!=null 然后您需要 False loader 并显示数据