保存从 Firestore 集合中的 JSON URL 获取的列表

Posted

技术标签:

【中文标题】保存从 Firestore 集合中的 JSON URL 获取的列表【英文标题】:Save list getting from JSON URL in firestore collection 【发布时间】:2021-05-10 15:16:30 【问题描述】:

我的小应用程序,正在从 JSON 链接获取用户列表,然后将其存储在列表中,我想将此列表放入 usersCollectionfirestore 的集合参考

我的代码

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:yat_flutter_app/main.dart';
import 'usersList.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class MyApp extends StatefulWidget 

  @override
  _MyAppState createState() => _MyAppState();


class _MyAppState extends State<MyApp> 

  CollectionReference usersCollection =
  FirebaseFirestore.instance.collection('users');

  Future<List<User>> getUsers() async 
    var data = await http
        .get("https://www.json-generator.com/api/json/get/bYKKPeXRcO?indent=2");
    var jasonData = json.decode(data.body);
    List<User> users = [];

    for (var i in jasonData) 
      User user = User(i["index"], i["about"], i["name"], i["picture"],
          i["company"], i["email"]);
      users.add(user);
    

    return users;
  


  @override
  Widget build(BuildContext context) 

    List<User> usersList = getUsers() as List<User>;


    return Container(

      child: Column(
        children: [
          FutureBuilder(
            future: getUsers(),
            builder: (BuildContext context, AsyncSnapshot asyncSnapshop) 
              if (asyncSnapshop.hasData) 
                return Expanded(
                  child: ListView.builder(
                      shrinkWrap: true,
                      itemCount: asyncSnapshop.data.length,
                      itemBuilder: (BuildContext context, int index) 
                        return Card(
                          elevation: 5,
                          color: Colors.cyan[50],
                          child: ListTile(
                            trailing: Icon(Icons.share),
                            title: Text(asyncSnapshop.data[index].name, style: TextStyle(fontFamily: 'Tahoma',fontSize: 20,fontWeight: FontWeight.bold),),
                            leading: CircleAvatar(
                              backgroundImage: NetworkImage(
                                  asyncSnapshop.data[index].picture +
                                      asyncSnapshop.data[index].index.toString() +
                                      ".jpg"),
                            ),
                            subtitle: Text(asyncSnapshop.data[index].email,style: TextStyle(fontFamily: 'Tahmoma',fontSize: 18),),
                            onTap: ()
                              Navigator.push(context, new MaterialPageRoute(builder: (context)=>
                                  detailsPage(asyncSnapshop.data[index])
                              ));
                            ,

                            onLongPress: ()=>

                                Fluttertoast.showToast(
                                    msg: asyncSnapshop.data[index].name,
                                    toastLength: Toast.LENGTH_SHORT,
                                    gravity: ToastGravity.CENTER,
                                    timeInSecForiosWeb: 1,
                                    backgroundColor: Colors.green[900],
                                    textColor: Colors.white,
                                    fontSize: 16.0
                                ),

                          ),
                        );
                      ),
                );
               else 
                return Text("Loading, please wait...");
              
            ,
          ),

          ElevatedButton(
              child: Text('Save data'),
              onPressed: () => 
                
      usersCollection.add(getUsers()); // here's I am trying to add the result of getUsers into usersCollection 

              ),
        ],

      ),
    );
  


【问题讨论】:

【参考方案1】:

Firebase 实时数据库和 Firestore 不是 SQL 数据库,数据将存储在父子关系或树结构中。

为了存储数据列表,您可以将列表转换为地图 地图可以如下初始化

Map<String, String> toMap() 
  return 
    'Fruit': "Mango",
    'Flower': "Lotus",
    'Vegetable': "Potato",
  ;

拥有 Map 后,您可以为 firestore 设置值。您可以使用以下代码设置值

Map<String, Object> city = new Map<>();
//Loop through your list and load Map (City) values
db.collection("cities").document("LA").set(city)
.addOnSuccessListener(new OnSuccessListener<Void>() 
    @Override
    public void onSuccess(Void aVoid) 
    Log.d(TAG, "DocumentSnapshot successfully written!");
    
).addOnFailureListener(new OnFailureListener() 
    @Override
    public void onFailure(@NonNull Exception e) 
    Log.w(TAG, "Error writing document", e);
    
);

您可以使用此将项目列表转换为地图

Java: How to convert List to Map

【讨论】:

存储地图数据是最简单的。因此,将您的 JSON 列表转换为地图或哈希图以使您的工作更轻松。如果您有更多疑问,可以在这里联系我。 第一种和第三种方法在这种情况下无效 @MML 好的,我已经编辑了对 Map 的答案并将 map 设置为 firestore。检查它是否有效【参考方案2】:

要将此列表推送到 Firestore,您需要在模型类中使用 fromJsontoJson 方法

 factory User.fromJson(Map<String, dynamic> data)
    return User(
        index: data['index'] as int,
        about: data['about'] as String,
        name: data['name'] as String,
        picture: data['picture'] as String,
        company: data['company'] as String,
        email: data['email'] as String );
  

  Map<String, dynamic> toJson()

    return 
        "index": index,
        "about" : about,
        "name" : name,
        "picture" : picture,
        "company" : company,
        "email" : email,
    ;
  

我建议使用json_serializable

那么你需要像这样对你未来的方法做一些改变

getUsers().then((users) 
// add users to map
);

然后您可以使用 fromJson 方法将其推送到 firestore 数据库

【讨论】:

【参考方案3】:

要将对象推送到 Firestore,您需要将 object 转换为 map。 您可以将此功能添加到您的课程中:

  Map<String, dynamic> toMap() 
    return 
      'field1': value1,
      'field2': value1,
    ;
  

要推送一个 List ,你需要将所有对象转换为 map ,你可以使用以下方法:

  static List<Map> ConvertToMap(List myList ) 
    List<Map> steps = [];
    myList.forEach((var value) 
      Map step = value.toMap();
      steps.add(step);
    );
    return steps;
  

或者简单地说,见 how to convert List to Map

希望对你有用

【讨论】:

感谢您的解释,我尝试获取getUsers(); 方法的结果并将其放入ConvertToMap(); 这样List list = convertToMap(getUsers()); 但它不起作用,我认为问题是因为该方法是Future 我觉得你应该把convertToMap函数变成一个异步函数来做这个 我尝试添加Future 但它无效A value of type 'List&lt;Map&lt;dynamic, dynamic&gt;&gt;' can't be returned from the method 'convertToMap' because it 我将等待解决方案如何将此未来列表的结果转换为动态地图列表(您的方法)

以上是关于保存从 Firestore 集合中的 JSON URL 获取的列表的主要内容,如果未能解决你的问题,请参考以下文章

从Firestore导出json

从 Firestore 导出 json

尝试在 google Firestore 中跨集合查询 [重复]

Firestore - 从集合中的文档中获取集合条目

如何按创建日期而不是名称对 Cloud Firestore 集合中的文档进行排序?

从firestore查询数据时,如何将保存的字符串格式的日期与当前日期进行比较?