Home > Software engineering >  Flutter - How can I print all my data (fields) from firebase documents?
Flutter - How can I print all my data (fields) from firebase documents?

Time:02-07

I would like to show all the fields of a document in firebase, but I'm having different troubles.

My intention is to show the info like a chat. I tried with a ListView.builder inside a StreamBuilder.

This is my Firestore document:

FirebaseImage

I managed to get the horizontal information using doc.data().toString but what I am trying to do is to get the whole information as a ListTile so when I add new messages they are automatically added to the ListView.builder.

This is my current code:

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

class ChatScreen extends StatefulWidget {
  const ChatScreen({Key? key}) : super(key: key);

  @override
  State<ChatScreen> createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  final textController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.only(left: 20.0),
        child: StreamBuilder(
            stream:
                FirebaseFirestore.instance.collection("messages").snapshots(),
            builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
              if (!snapshot.hasData) {
                return Center(child: CircularProgressIndicator());
              }
              return ListView.builder(
                itemCount: snapshot.data!.docs.length,
                itemBuilder: (context, index) {
                  DocumentSnapshot doc = snapshot.data!.docs[index];
                  return ListTile(
                    title: Text(doc.data().toString()),
                  );
                },
              );
            }),
      ),
    );
  }
}

And this is what I get with my current code: DeviceImage

P.S. I can get the data manually if I use this but it's not what I want:

return ListTile(
                    title: Text(doc['sender']),
                  );

CodePudding user response:

Try to use an Object like below.

class Message {
  final String sender;
  final String text;

  const Message({
    required this.sender,
    required this.text,
  });

  Map<String, dynamic> toMap() {
    return {
      'sender': sender,
      'text': text,
    };
  }

  factory Message.fromMap(Map<String, dynamic> map) {
    return Message(
      sender: map['sender'] as String,
      text: map['text'] as String,
    );
  }
}

class ChatScreen extends StatelessWidget {
  const ChatScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<List<Message>>(
        stream: FirebaseFirestore.instance
            .collection("messages")
            .snapshots()
            .map((query) =>
                query.docs.map((map) => Message.fromMap(map.data())).toList()),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return const Center(child: CircularProgressIndicator());
          }
          final msgList = snapshot.data!;
          return ListView.builder(
            itemCount: msgList.length,
            itemBuilder: (context, index) {
              final message = msgList[index];
              return ListTile(
                title: Text(message.text),
                leading: Text(message.sender),
              );
            },
          );
        });
  }
}

CodePudding user response:

Try with this.

return StreamBuilder<QuerySnapshot>(
      stream: FirebaseFirestore.instance
          .collection("messages")
          .snapshots(),
      builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
        return ListView.builder(
          shrinkWrap: true,
          primary: false,
          itemCount: snapshot.hasData ? snapshot.data.docs.length : 0,
          itemBuilder: (context, index) {
            final data = MessageModel.fromSnapshot(snapshot.data.docs[index]);
            return ListTile(
              title: Text(data.text),
              subtitle: Text(data.sender),
            );
          },
        );
      },
    );

MessageModel

class MessageModel {
  MessageModel({
    this.sender,
    this.text,
  });

  String sender;
  String text;

  String toRawJson() => json.encode(toJson());

  factory MessageModel.fromSnapshot(DocumentSnapshot snapshot) {
    final model =
        MessageModel.fromJson(snapshot.data() as Map<String, dynamic>);
    return model;
  }

  factory MessageModel.fromJson(Map<String, dynamic> json) => MessageModel(
        sender: json["sender"] == null ? null : json["sender"],
        text: json["text"] == null ? null : json["text"],
      );

  Map<String, dynamic> toJson() => {
        "sender": sender == null ? null : sender,
        "text": text == null ? null : text,
      };
}
  •  Tags:  
  • Related