3

My small app, is getting list of users from JSON link then store it in the List, I wanna this list into usersCollection collection ref of firestore

usersCollection

my code

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 

              }),
        ],

      ),
    );
  }
}

3 Answers3

2

To push an object to Firestore you need to convert your object to map.
You can just add this function to your class:

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

To push a List , you need to convert all objects to map, you can do it with following method:

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

Or simply , see how to convert List to Map

I hope it will be useful

Kab Agouda
  • 6,309
  • 38
  • 32
  • Thanks for explaining , I tried to getting the result of `getUsers();` method and put it into `ConvertToMap();` like this `List list = convertToMap(getUsers());` but it's not working, I think the problem is because the method is Future – Indiana Evans Feb 09 '21 at 05:19
  • I think you should turn the convertToMap function into an asynchronous function to do this – Kab Agouda Feb 09 '21 at 05:40
  • I tried to add `Future` to it but it's not valid `A value of type 'List>' can't be returned from the method 'convertToMap' because it` I'll waiting to for the solution how to convert the result of this future list to dynamic map list (your method) – Indiana Evans Feb 09 '21 at 10:29
1

Firebase realtime database and firestore are no SQL databases where data will be stored in Parent child relation or Tree structure.

For you to store list of data you can convert your list into Map Map can be initialised as follows

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

After you have Map you can set value to the firestore. You can use the below code to set value

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

You can convert List of items to map using this

Java: How to convert List to Map

1

To push this list to Firestore you need to fromJson and toJson methods in your model class

 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,
    };
  }

instead that I would like to suggest using json_serializable library

then you need to do some changes in your future method like this

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

and then you can use fromJson method to push it to firestore database

Dr Mido
  • 2,414
  • 4
  • 32
  • 72