Flutter使用GetX如何从Firebase获取restaurants节点下所有子层级数据


实现方案
1. 新建GetX Controller管理数据流
创建restaurant_controller.dart文件,代码如下:
import 'package:get/get.dart'; import 'package:firebase_database/firebase_database.dart'; class RestaurantController extends GetxController { // 响应式变量,存储menu节点下所有子节点数据 final RxMap<String, dynamic> menuItems = <String, dynamic>{}.obs; late StreamSubscription<DatabaseEvent> _menuStreamSub; @override void onInit() { super.onInit(); // 监听menu节点的所有数据变动 final menuRef = FirebaseDatabase.instance.ref("restaurants/swad/menu"); _menuStreamSub = menuRef.onValue.listen((event) { if (event.snapshot.exists) { final Map data = event.snapshot.value as Map; // 转换格式后赋值给响应式变量,自动包含apple、among us、plant等所有子节点 menuItems.assignAll(data.map((key, value) => MapEntry(key.toString(), value))); } else { menuItems.clear(); } }); } @override void onClose() { // 取消订阅避免内存泄漏 _menuStreamSub.cancel(); super.onClose(); } }
2. 注册Controller
在应用初始化时全局注册Controller:
void main() { Get.put(RestaurantController()); runApp(const MyApp()); }
3. UI层使用数据
无需编写StreamBuilder,直接通过Obx监听响应式变量渲染UI即可:
class MenuPage extends StatelessWidget { MenuPage({super.key}); final RestaurantController controller = Get.find<RestaurantController>(); @override Widget build(BuildContext context) { return Scaffold( body: Obx(() => ListView.builder( padding: const EdgeInsets.all(16), itemCount: controller.menuItems.length, itemBuilder: (context, index) { String itemName = controller.menuItems.keys.elementAt(index); dynamic itemInfo = controller.menuItems[itemName]; return ListTile( title: Text(itemName), subtitle: Text(itemInfo['desc'] ?? '暂无描述'), trailing: Text("¥${itemInfo['price'] ?? '0'}"), ); }, )), ); } }
异常排查
如果仍无法读取子节点,优先检查两个配置:
- Firebase Realtime Database的读权限规则是否开放了
restaurants/swad/menu路径的访问权限 - 监听的路径拼写是否和数据库实际结构完全一致,注意大小写、符号完全匹配
内容的提问来源于stack exchange,提问作者Chinmaya Garnaik
相关产品推荐
相关产品推荐

