skip to Main Content

I try to retrieve the imageLink saved in a Firestore collection of userProfile, but I can’t retrieve the data and it displays the following errors. Does anyone know why this happens and how to fix it?

Error

The following _TypeError was thrown building StreamBuilder<DocumentSnapshot<Object?>>(dirty, state:
    _StreamBuilderBaseState<DocumentSnapshot<Object?>, AsyncSnapshot<DocumentSnapshot<Object?>>>#dbdf2):
    type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast**
    
The relevant error-causing widget was:
  StreamBuilder<DocumentSnapshot<Object?>>
  StreamBuilder:file:///C:/Users/project/lib/views/profile_page.dart:173:34

    When the exception was thrown, this was the stack:
    #0      _ProfilePageState.build.<anonymous closure>.<anonymous closure> (package:success_auto/views/profile_page.dart:181:39)
    profile_page.dart:181
    #1      StreamBuilder.build (package:flutter/src/widgets/async.dart:439:81)
    async.dart:439
    #2      _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:120:48)
    async.dart:120
    #3      StatefulElement.build (package:flutter/src/widgets/framework.dart:5409:27)
    framework.dart:5409
    #4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5297:15)
    framework.dart:5297
    #5      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5462:11)
    framework.dart:5462
    #6      Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
    framework.dart:5016
    #7      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2779:19)
    framework.dart:2779
    #8      WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:916:21)
    binding.dart:916
    #9      RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:360:5)
    binding.dart:360
    #10     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1297:15)
    binding.dart:1297
    #11     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1227:9)
    binding.dart:1227
    #12     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1085:5)
    binding.dart:1085
    #13     _invoke (dart:ui/hooks.dart:170:13)
    hooks.dart:170
    #14     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:401:5)
    platform_dispatcher.dart:401
    #15     _drawFrame (dart:ui/hooks.dart:140:31)
    hooks.dart:140

Code

class ProfilePage extends StatefulWidget {
  const ProfilePage({super.key});

  @override
  State<ProfilePage> createState() => _ProfilePageState();
}

class _ProfilePageState extends State<ProfilePage> {
  // Added Part
  final FirebaseStorage _storage = FirebaseStorage.instance;
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;

  // current user
  final currentUser = FirebaseAuth.instance.currentUser!;
  late String imageUrl;

  Future<String> uploadImageToStorage(String childName, Uint8List file) async {
    Reference ref = _storage.ref().child(childName);
    UploadTask uploadTask = ref.putData(file);
    TaskSnapshot snapshot = await uploadTask;
    String downloadUrl = await snapshot.ref.getDownloadURL();
    print(downloadUrl);
    return downloadUrl;
  }

  Future<String> saveData({
    required String id,
    required String name,
    required Uint8List file,
  }) async {
    String resp = " Some Error Occurred";
    try {
      if (name.isNotEmpty) {
        String imageUrl = await uploadImageToStorage('profileImage', file);
        await _firestore.collection('userProfile').add({
          'id': FirebaseAuth.instance.currentUser!.uid,
          'name': name,
          'imageLink': imageUrl,
        });
        resp = 'success';
      }
    } catch (err) {
      resp = err.toString();
    }
    return resp;
  }

  // edit field
  Future<void> editField(String field) async {
    String newName = '';
    await showDialog(
      context: context,
      builder: (context) => AlertDialog(
        backgroundColor: Colors.grey[900],
        title: Text(
          'Edit $field',
          style: const TextStyle(
            color: Colors.white,
          ),
        ),
        content: TextField(
          autofocus: true,
          style: const TextStyle(color: Colors.white),
          decoration: InputDecoration(
            hintText: 'Enter new $field',
            hintStyle: const TextStyle(color: Colors.grey),
          ),
          onChanged: (value) {
            newName = value;
          },
        ),
        actions: [
          // cancel button
          TextButton(
            child: const Text(
              'Cancel',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () => Navigator.pop(context),
          ),
          // save button
          TextButton(
            child: const Text(
              'Save',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () => Navigator.of(context).pop(newName),
          ),
        ],
      ),
    );

    // update profile details in Firebase Firestore
    if (newName.trim().isNotEmpty) {
      // only update if there is something in the textfield
      await FirebaseFirestore.instance
          .collection('Users')
          .doc(currentUser.email)
          .update({field: newName});
    }
  }

  // change image
  Uint8List? _image;
//  File? image;

  void selectImage() async {
    Uint8List img = await pickImage(ImageSource.gallery);
    setState(() {
      _image = img;
      print('Image path: $_image');
    });
  }

  void saveProfile() async {
    String id;
    String resp = await StoreData().saveData(
      id: FirebaseAuth.instance.currentUser!.uid,
      name: currentUser.email as String,
      file: _image!,
    );
    print(resp);
    const SnackBar(
      content: Text(
        'Save',
        style: TextStyle(color: Colors.green),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: const Text('Profile Page'),
        backgroundColor: primaryClr,
      ),
      drawer: const DrawerListBar(),
      body: Container(
        padding: const EdgeInsets.symmetric(horizontal: 32),
        child: StreamBuilder<DocumentSnapshot>(
          stream: FirebaseFirestore.instance
              .collection('Users')
              .doc(currentUser.email)
              .snapshots(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              final userData = snapshot.data!.data() as Map<String, dynamic>;
              return Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Expanded(
                    child: ListView(
                      children: [
                        const SizedBox(height: 20),
                        Center(
                          child: StreamBuilder<DocumentSnapshot>(
                              stream: FirebaseFirestore.instance
                                  .collection('userProfile')
                                  .doc()
                                  .snapshots(),
                              builder: (context, snapshot) {
                                if (snapshot.hasData) {
                                  final userPicture = snapshot.data!.data()
                                      as Map<String, dynamic>;
                                  return Stack(
                                    children: [
                                      _image != null
                                          ? CircleAvatar(
                                              radius: 64,
                                              backgroundImage: NetworkImage(
                                                  userPicture['imageLink']),
                                            )
                                          : const CircleAvatar(
                                              radius: 64,
                                              backgroundImage: NetworkImage(
                                                  'https://png.pngitem.com/pimgs/s/421-4212266_transparent-default-avatar-png-default-avatar-images-png.png'),
                                            ),
                                      Positioned(
                                        bottom: -10,
                                        left: 80,
                                        child: IconButton(
                                          onPressed: selectImage,
                                          icon: const Icon(Icons.add_a_photo),
                                        ),
                                      ),
                                    ],
                                  );
                                } else if (snapshot.hasError) {
                                  Get.snackbar(
                                    'Error',
                                    'Error${snapshot.error}',
                                    backgroundColor: Colors.white,
                                    snackPosition: SnackPosition.BOTTOM,
                                    colorText: Colors.black,
                                    icon: const Icon(
                                      Icons.warning_amber_rounded,
                                      color: Colors.red,
                                    ),
                                  );
                                }
                                return const EmptyContentsAnimationView();
                              }),
                        ),
                        const SizedBox(height: 20),
                        Text(
                          currentUser.email!,
                          textAlign: TextAlign.center,
                          style: const TextStyle(color: Colors.black),
                        ),

                        const SizedBox(height: 50),
                        // user details
                        const Padding(
                          padding: EdgeInsets.only(left: 25.0),
                          child: Text(
                            'My Details',
                            style: TextStyle(color: Colors.black),
                          ),
                        ),
                        // username
                        ProfileTextBox(
                          text: userData['username'],
                          sectionName: 'username',
                          onPressed: () => editField('username'),
                        ),
                        const SizedBox(height: 50),
                        TextButton.icon(
                          onPressed: saveProfile,
                          icon: const Icon(Icons.save),
                          label: const Text('Save'),
                        ),
                      ],
                    ),
                  ),
                ],
              );
            } else if (snapshot.hasError) {
              Get.snackbar(
                'Error',
                'Error${snapshot.error}',
                backgroundColor: Colors.white,
                snackPosition: SnackPosition.BOTTOM,
                colorText: Colors.black,
                icon: const Icon(
                  Icons.warning_amber_rounded,
                  color: Colors.red,
                ),
              );
            }
            return const EmptyContentsAnimationView();
          },
        ),
      ),
    );
  }
}

UI

Firebase Firestore

2

Answers


  1. Make sure that the document with the specified ID exists in the Firestore collection.

    Before accessing any field, check if the document exists and the field is not null to avoid the error you mentioned.

    And you are using "snapshot" identifier for collection("Users") and collection("userProfile").Try to use different identifiers and try again.

    Login or Signup to reply.
  2. Your’e using the null operator (!) in your code:

    userData = snapshot.data!.data() as Map<String, dynamic>;
    

    And:

    final userPicture = snapshot.data!.data() as Map<String, dynamic>;
    

    The ! is the issue if snapshot.data is null. The ! operator is a null assertion operator in Dart, which tells the compiler that you are certain the value is not null. However, in this case it is.

    Instead, what you can use is a ? — which tells that it can be null:

    if (snapshot.hasData && snapshot.data?.data() != null) {
        final userData = snapshot.data!.data() as Map<String, dynamic>;
        // Rest of your code
    } else {
        // Handle the situation when snapshot.data is null
        // and investigate your DB.
    }
    
    

    or maybe even instead:

    final userData = snapshot.data?.data() as Map<String, dynamic>?;
    

    With a ? instead of !.

    See also

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search