如何从 Firebase 实时数据库中获取数据到 Flutter 中的列表中?
Posted
技术标签:
【中文标题】如何从 Firebase 实时数据库中获取数据到 Flutter 中的列表中?【英文标题】:How to get data from Firebase Realtime Database into list in Flutter? 【发布时间】:2020-08-13 21:50:48 【问题描述】:我正在尝试使用模型将 Firebase 实时数据库中的数据检索到 Flutter 中的列表中。当我这样做时,我的列表返回为空。我已经阅读了其他几篇关于在 Flutter 中使用 Firebase 的文章,但还没有找到明确的答案。这是我目前的方法(该对象称为“需求”,我正在尝试检索并显示需求列表):
型号:
import 'package:firebase_database/firebase_database.dart';
class Need
final String id;
final String imageUrl;
final String caption;
final String title;
Need(
this.id,
this.imageUrl,
this.caption,
this.title,
);
Need.fromSnapshot(DataSnapshot snapshot) :
id = snapshot.key,
imageUrl = snapshot.value["imageUrl"],
caption = snapshot.value["caption"],
title = snapshot.value["postTitle"];
toJson()
return
"imageUrl": imageUrl,
"caption": caption,
"title": title,
;
带有 Firebase 查询的数据库服务:
import 'package:firebase_database/firebase_database.dart';
import 'package:Given_Flutter/models/need_model.dart';
class DatabaseService
static Future<List<Need>> getNeeds() async
Query needsSnapshot = await FirebaseDatabase.instance
.reference()
.child("needs-posts")
.orderByKey();
print(needsSnapshot); // to debug and see if data is returned
List<Need> needs;
Map<dynamic, dynamic> values = needsSnapshot.data.value;
values.forEach((key, values)
needs.add(values);
);
return needs;
列表视图:
import 'package:flutter/material.dart';
import 'package:Given_Flutter/models/need_model.dart';
import 'package:Given_Flutter/services/database_service.dart';
import 'package:Given_Flutter/need_view.dart';
class Needs extends StatefulWidget
static final String id = 'needs_screen';
@override
_NeedsState createState() => _NeedsState();
class _NeedsState extends State<Needs>
List<Need> _needs = [];
@override
void initState()
super.initState();
_setupNeeds();
_setupNeeds() async
List<Need> needs = await DatabaseService.getNeeds();
setState(()
_needs = needs;
);
@override
Widget build(BuildContext context)
return Scaffold(
body: RefreshIndicator(
onRefresh: () => _setupNeeds(),
child: ListView.builder(
itemCount: _needs.length,
itemBuilder: (BuildContext context, int index)
Need need = _needs[index];
return NeedView(
need: need,
);
)
)
);
Firebase 实时数据库结构:
Firebase example
我做错了什么?
【问题讨论】:
你的调试打印输出什么? @GrahamD 这行显示错误: MapMap<dynamic, dynamic> values = needsSnapshot.data.value;
错误。
值是数据,所以只需使用Map<dynamic, dynamic> values = needsSnapshot.value;
您附加到列表的对象也没有转换..
// wrong
Map<dynamic, dynamic> values = needsSnapshot.data.value;
values.forEach((key, values)
needs.add(values);
);
// correct
Map<dynamic, dynamic> values = needsSnapshot.data.value;
values.forEach((key, values)
needs.add(Need.fromSnapshot(values));
);
还有一件事,我对此不是 100% 确定的,但是如果我将 List 声明为 null 我在为其添加值时会遇到问题,所以我总是将其声明为空列表。
所以我会使用List<Need> needs = [];
而不是List<Need> needs;
希望您已经解决了它,但如果没有,这应该可以。我刚刚遇到了同样的问题.. 干杯
【讨论】:
我设法根据您的解决方案获取数据,但是,当我返回列表时,它是空的(因为返回发生在将数据添加到 forEach() 中的列表之前)。你知道我能做些什么,这样在我的 forEach() 完成之前返回不会执行吗?它还告诉我查询之前的等待什么也不做。 @DanCrisan 嗨,问题应该是你没有将你的方法声明为async
这就是为什么await
没有做任何事情并且它返回一个空的List
它不等待结果填充它并返回声明的空。让我知道这是否解决了它。干杯。
您好,我的方法肯定是声明为async的,否则我认为尝试使用await时会出错。相反,我只是收到一个警告,说它没有做任何事情。如果我在查询结束时使用 .once() 之类的东西,那么 await 可以工作,但是,它会将我的查询转换为 DataSnapshot,而我需要它是一个查询。
@DanCrisan 请分享一些代码,以便我查看并尝试找出问题;)
我已经把代码贴在这里了:***.com/q/64277935/10544887【参考方案2】:
试试这个
needsSnapshot.once().then((DataSnapshot snapshot)
print(snapshot.value.entries.length);
for (var val in snapshot.value.entries)
needs.add(new Need(val.id, val.imageUrl,val.caption,val.title));
//print(val.value.toString());
//print(needs.length);
【讨论】:
【参考方案3】:请注意,如果上述方法有效,则可以实现以下效果:
List<Need> yourNeeds=[];
await firestore.collection("Need")
.getDocuments()
.then((QuerySnapshot snapshot)
snapshot.documents.forEach((f)
Needs obj= new Need();
obj.field1=f.data['field1'].toString();
obj.field2=f.data['field2'].toDouble();
//Adding value to your Need list
yourNeeds.add(obj);
);
【讨论】:
【参考方案4】:创建一个模型来容纳对象。在其中创建一个方法,如下所示,
ModelName.fromJson(Map<String, dynamic> json)
property1 = json['property1'];
property2 = json['property2'];
使用以下方法直接将firebase数据快照转换为模型。
databaseRef.once().then((DataSnapshot snapshot)
for(var data in snapshot.value)
var model = Model.fromJson(Map<String, dynamic>.from(data));
logger.i(model.iponame);
);
【讨论】:
以上是关于如何从 Firebase 实时数据库中获取数据到 Flutter 中的列表中?的主要内容,如果未能解决你的问题,请参考以下文章