I am getting data from Firebase Database and Adding it to a List of my Model class. I tested the incoming data by printing to Console and it works fine, but once i add the data to my model class, it disappears.

Here's my Provider class where i'm loading the data.

import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:local_stuffs_notification/apis/fcm.dart';
import 'package:local_stuffs_notification/models/request_model.dart';
import 'package:shared_preferences/shared_preferences.dart';

class IncomingRequest with ChangeNotifier {
  List<RequestModel> _incomingRequests = [];
  IncomingRequest(this._incomingRequests);

  List<RequestModel> get incomingRequest {
    return [..._incomingRequests];
  }

  Future<void> setIncomingRequest(RequestModel requestModel) async {
    try {
      DatabaseReference reference =
          FirebaseDatabase.instance.ref("incomingRequests");
      reference.child(requestModel.id).child(Fcm.getUid()).set(
        {
          "name": requestModel.name.toString(),
          "phone": requestModel.phone.toString(),
          "email": requestModel.email.toString(),
          "fcmToken": requestModel.fcmToken.toString(),
        },
      );
      notifyListeners();
    } catch (error) {
      rethrow;
    }
  }

  Future<void> loadIncomingRequests() async {
    try {
      SharedPreferences preferences = await SharedPreferences.getInstance();
      DatabaseReference reference = FirebaseDatabase.instance
          .ref('incomingRequests/${preferences.getString('userId')!}');
      Stream<DatabaseEvent> stream = reference.onValue;
      stream.listen((DatabaseEvent event) {
        print(event.snapshot.value);
        final data = event.snapshot.value as Map;
        print('data: $data');
        final List<RequestModel> loadedRequest = [];
        data.forEach(
          (key, value) {
            print('requestData: ${value['name']}');
            loadedRequest.add(
              RequestModel(
                id: key.toString(),
                name: value['name'].toString(),
                fcmToken: value['fcmToken'].toString(),
                phone: value['phone'].toString(),
                email: value['email'].toString(),
              ),
            );
            print(loadedRequest);
          },
        );
        _incomingRequests = loadedRequest;
        print('LoadedRequests: $loadedRequest');
        notifyListeners();
      });
      // reference.onValue.listen(
      //   (event) {
      //     if (event.snapshot.value == null) {
      //       return;
      //     }
      //     final data = event.snapshot.value as Map;
      //     final List<RequestModel> loadedRequests = [];
      //     data.forEach(
      //       (key, requestData) {
      //         loadedRequests.add(
      //           RequestModel(
      //             id: key,
      //             name: requestData['name'],
      //             fcmToken: requestData['fcmToken'],
      //             phone: requestData['phone'],
      //             email: requestData['email'],
      //           ),
      //         );
      //       },
      //     );
      //     _incomingRequests = loadedRequests;
      //     notifyListeners();
      // },
      //);
    } catch (error) {
      rethrow;
    }
  }
}

Here's my Model Class

class RequestModel {
  final String id;
  final String name;
  final String fcmToken;
  final String phone;
  final String email;

  RequestModel({
    required this.id,
    required this.name,
    required this.fcmToken,
    required this.phone,
    required this.email,
  });
}

I'm getting the data until i added it to loadedRequest List

Please help, i've spent hours on this and i don't know what i'm doing wrong. When i print the loadedRequest list, i get an empty list. Thanks.


Solution 1: Michael Horn

Those logs aren't showing an empty list - It says [Instance of 'RequestModel']. That means there is a value there, but Dart simply doesn't know how to convert RequestModel to a String so that it can be printed out on the console.

An empty list would be printed simply as [], and if you had two values, for example, you would see [Instance of 'RequestModel', Instance of 'RequestModel'].

To print out your values with more detail, you can override the toString() method on your class.

For example:

class RequestModel {
  final String id;
  final String name;
  final String fcmToken;
  final String phone;
  final String email;

  RequestModel({
    required this.id,
    required this.name,
    required this.fcmToken,
    required this.phone,
    required this.email,
  });

  @override
  String toString() => 
    "RequestModel(id: $id, name: $name, fcmToken: $fcmToken, phone: $phone, email: $email)";
}


Solution 2: mohamed.oussous

take a look at the raw data once again, it contains all the users data so you need to get the access the uid before the name

final uid = FirebaseAuth.instance.currentUser!.uid;

and then for the RequestModel:

name: data[uid]['name']