6

I am trying to map a DocumentSnap from Firebase to a Json Class in Flutter. I can confirm that my is getting the data from the document, but i cannot pass the gathered data to my Json object. I have attached code and error message.

Class for getting the document from Firebase DatabaseService.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'package:oast_app/widgets/auth_class.dart';



class FireTest {
  Future<List<UserCheck>> streamUser(FirebaseUser user) async {
    DocumentSnapshot querySnapshot =
        await Firestore.instance.collection('users').document(user.uid).get();
    if (querySnapshot.exists) {
      print('success');
      print(querySnapshot.data['fname']);
      print(querySnapshot.data['lname']);

      querySnapshot.data.map<String, dynamic>((json) => UserCheck.fromJson(json)); **this is whats erroring**
    }
    return [];
  }
}

Json Object class

import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart';

part 'auth_class.g.dart';

@JsonSerializable(nullable: false)
class UserCheck extends ChangeNotifier {
  final String uid;
  final String fName;
  final String lName;
  final String regEmail;
  final String org;

  UserCheck({
    this.uid,
    this.fName,
    this.lName,
    this.regEmail,
    this.org,
  });

  factory UserCheck.fromJson(Map<String, dynamic> json) =>
      _$UserCheckFromJson(json);

  Map<String, dynamic> toJson() => _$UserCheckToJson(this);
}

Error Message

Compiler message: lib/widgets/database_service.dart:17:76: Error: The argument type 'String' can't be assigned to the parameter type 'Map<String, dynamic>'.

  • 'Map' is from 'dart:core'. querySnapshot.data.map<String, dynamic>((json) => UserCheck.fromJson(json)); ^ lib/widgets/database_service.dart:17:67: Error: A value of type 'UserCheck' can't be assigned to a variable of type 'MapEntry<String, dynamic>'.
  • 'UserCheck' is from 'package:oast_app/widgets/auth_class.dart' ('lib/widgets/auth_class.dart').
  • 'MapEntry' is from 'dart:core'. querySnapshot.data.map<String, dynamic>((json) => UserCheck.fromJson(json)); ^ lib/widgets/database_service.dart:17:47: Error: The argument type 'MapEntry<String, dynamic> Function(String)' can't be assigned to the parameter type 'MapEntry<String, dynamic> Function(String, dynamic)'.
  • 'MapEntry' is from 'dart:core'. querySnapshot.data.map<String, dynamic>((json) => UserCheck.fromJson(json));

firebase structure

enter image description here ^ collection('users').document('user.uid') this is the document im trying to get

Dan Bonachea
  • 2,408
  • 5
  • 16
  • 31
David Escobar
  • 81
  • 1
  • 3
  • 8
  • do you want to convert documentsnapshot to data class right? – BIS Tech Dec 12 '19 at 00:06
  • Yes, what’s in my UserCheck class which is for Json – David Escobar Dec 12 '19 at 00:21
  • Instead of using map operation, use 'for each'. querySnapshot.data.forEach((json) => UserCheck.fromJson(json)); – Alvindrakes Dec 12 '19 at 04:55
  • @Alvindrakes made the change, new error, Compiler message: lib/widgets/database_service.dart:16:63: Error: The argument type 'String' can't be assigned to the parameter type 'Map'. - 'Map' is from 'dart:core'. querySnapshot.data.forEach((json) => UserCheck.fromJson(json)); – David Escobar Dec 12 '19 at 05:03
  • Could you edit your question with a screenshot of your firestore data structure, that way it would be easier for us to understand the incoming data. – Alvindrakes Dec 12 '19 at 05:05
  • updated, its a link, stackoverflow didnt let me post the image directly @Alvindrakes – David Escobar Dec 12 '19 at 05:11
  • If you look at the error console, it says the parameter needed is a Map. When you pass in the data, you only pass in the Json. So I would say you should do => querySnapshot.data.forEach((json) => UserCheck.fromJson(json.data, json.documentID )) – Alvindrakes Dec 12 '19 at 05:37
  • @Alvindrakes no change same errors – David Escobar Dec 12 '19 at 05:47

3 Answers3

4

Assuming that you have the collection name as "tblcustomers",

Stream<QuerySnapshot> stream = _db.collection("tblcustomers").snapshots();
  jsonObject = Customers(error: false, errorCode: 0, Items: List<Customers_items>());
  stream.forEach((QuerySnapshot element) {
    if (element == null) return;

    setState(() {
      jsonObject.Items = element.documents.map((e) => Customers_items.fromJson(e.data)).toList();
    });
  });
Ashwin Balani
  • 745
  • 7
  • 19
0

Your target type that you set at the map has to be the type that you want as result of the map.

So it should be

querySnapshot.data.map((json) => UserCheck.fromJson(json)).toList();

Thomas
  • 8,397
  • 7
  • 29
  • 39
  • made changes, multiple errors, Compiler message: lib/widgets/database_service.dart:15:59: Error: The argument type 'String' can't be assigned to the parameter type 'Map'. - 'Map' is from 'dart:core'. querySnapshot.data.map((json) => UserCheck.fromJson(json)).toList(); lib/widgets/database_service.dart:15:50: Error: A value of type 'UserCheck' can't be assigned to a variable of type 'MapEntry'. - 'UserCheck' is from 'package:oast_app/widgets/auth_class.dart' ('lib/widgets/auth_class.dart'). – David Escobar Dec 13 '19 at 03:32
  • Have to have a closer look at OK tomorrow. – Thomas Dec 13 '19 at 03:48
0
 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: FutureBuilder<DocumentSnapshot<Map<String, dynamic>>>(
        future: FirebaseFirestore.instance
            .collection('users')
            .doc(FirebaseAuth.instance.currentUser!.uid)  //  Your document id change accordingly
            .get(),
        builder: (_, snapshot) {
          if (snapshot.hasError) return Text('Error = ${snapshot.error}');
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Text("Loading");
          }
          
          UserCheck data = UserCheck.fromJson( snapshot.data!.data()!) //  Here you have to use fromJson method 

          return Text(data.fName); // Your data parameter here
        },
      )),
    );
  }

Also refer: How to use StreamBuilder and FutureBuilder for single and multiple documents`

krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88