Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将Firebase实时数据库中的数据输入到Flatter中的列表中?_Firebase_Flutter_Firebase Realtime Database_Dart - Fatal编程技术网

如何将Firebase实时数据库中的数据输入到Flatter中的列表中?

如何将Firebase实时数据库中的数据输入到Flatter中的列表中?,firebase,flutter,firebase-realtime-database,dart,Firebase,Flutter,Firebase Realtime Database,Dart,我正在尝试使用一个模型从Firebase实时数据库中检索数据,并将其放入Flatter中的列表中。执行此操作时,我的列表返回为空。我读过其他几篇关于使用Firebase和Flitter的帖子,但没有找到明确的答案。以下是我当前的方法(对象称为“需求”,我正在尝试检索并显示需求列表): 型号: import 'package:firebase_database/firebase_database.dart'; class Need { final String id; final Str

我正在尝试使用一个模型从Firebase实时数据库中检索数据,并将其放入Flatter中的列表中。执行此操作时,我的列表返回为空。我读过其他几篇关于使用Firebase和Flitter的帖子,但没有找到明确的答案。以下是我当前的方法(对象称为“需求”,我正在尝试检索并显示需求列表):

型号:

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'包:firebase_数据库/firebase_数据库.dart';
导入“包:给定\颤振/模型/需要\模型.省道”;
类数据库服务{
静态未来getNeeds()异步{
Query needsSnapshot=wait FirebaseDatabase.instance
.reference()
.child(“需要职位”)
.orderByKey();
print(needsSnapshot);//调试并查看是否返回数据
列出需要;
映射值=needsSnapshot.data.value;
values.forEach((键,值){
需要。增加(价值);
});
返回需求;
}
}
列表视图:

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,
            );
          }
        )
      )
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“包:给定\颤振/模型/需要\模型.省道”;
导入“package:Given_flatter/services/database_service.dart”;
导入“包:给定的颤振/需要视图.省道”;
类需要扩展StatefulWidget{
静态最终字符串id='needs_screen';
@凌驾
_NeedsState createState()=>\u NeedsState();
}
类_NeedsState扩展状态{
列表_需要=[];
@凌驾
void initState(){
super.initState();
_设置需要();
}
_setupNeeds()异步{
List needs=wait DatabaseService.getNeeds();
设置状态(){
_需要=需要;
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:刷新指示器(
onRefresh:()=>\u setupNeeds(),
子项:ListView.builder(
itemCount:_需要.length,
itemBuilder:(构建上下文,int索引){
需要=_需要[索引];
返回需要视图(
需要:需要,,
);
}
)
)
);
}
}
Firebase实时数据库结构:

我做错了什么?

Map values=needsSnapshot.data.value是错误的

值就是数据,所以只需使用
Map 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));
    });
//错了
映射值=needsSnapshot.data.value;
values.forEach((键,值){
需要。增加(价值);
});
//正确的
映射值=needsSnapshot.data.value;
values.forEach((键,值){
添加(Need.fromSnapshot(value));
});
还有一件事,我不是100%确定,但是如果我声明我的列表为空,我在向它添加值时会遇到问题,所以我总是将列表声明为空。。 因此,不是<代码>列表需要我会使用
列表需求=[]

希望你已经解决了它,但如果没有,这应该工作。我也遇到了同样的问题。。
干杯

请注意,如果上述措施奏效,也可以实现以下目的:

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);
});
列出您的需求=[];
等待firestore.收集(“需要”)
.getDocuments()
.然后((QuerySnapshot快照){
snapshot.documents.forEach((f){
需要obj=新的需要();
obj.field1=f.data['field1'].toString();
obj.field2=f.data['field2'].toDouble();
//为你的需求清单增加价值
添加(obj);
});
试试这个

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);

调试打印输出是什么?@GrahamD它显示了此行的一个错误:Map values=needsSnapshot.data.value;错误:没有为类“Query”定义getter“data”。@GrahamD我已尝试删除该行和以下forEach循环,以便只关注是否从Firebase获取数据。当我这样做时,调试日志将显示为never打印快照数据,即使我有一个打印行。我无法判断这是因为没有执行该部分,还是因为快照为null。相反,调试日志显示错误“getter'length'在null上被调用”,这是有意义的,因为返回到ListView的需求列表是空的。请尝试在代码行中使用needsSnapshot.value而不是needsSnapshot.data.value:Map values=needsSnapshot.data.value;我建议您添加一些打印语句作为策略点,以查看您实际获得的内容。我认为您无法打印快照无论如何,您将只获取快照的实例,您必须打印其属性,例如.key、.value我根据您的解决方案获取了数据,但是,当我返回列表时,它是空的(因为返回发生在forEach()中将数据添加到列表之前).你知道我能做些什么吗?这样在我的forEach()之前,返回不会执行完成?它还告诉我在查询之前等待什么都不做。@DanCrisan Hi,问题应该是你没有将你的方法声明为
async
,这就是为什么
await
没有做任何事情,它返回一个空的
列表
它没有等待填充它的结果并返回声明的空值。如果这就解决了问题。干杯。嗨,我的方法肯定声明为async,否则我认为它在尝试使用Wait时会出错。相反,我只会收到一条警告,说它不起任何作用。如果我使用类似.once()的东西但是,在查询结束时,Wait works将我的查询转换为DataSnapshot,而我需要它作为查询。@DanCrisan请共享一些代码,以便我可以查看它并尝试发现问题;)我已在此处发布了代码: