Flutter: Late Initialization Error for Fire Base Storage Image Upload

370

Posting rickimaru's solution as a Community wiki for visibility:

You need to replace the late String imageUrl with String? imageUrl to fix the initialization error.

Share:
370
adamcapjones
Author by

adamcapjones

Updated on December 06, 2022

Comments

  • adamcapjones
    adamcapjones over 1 year

    I am trying to allow signed in users upload profile pictures to their homepages. Before I added the uploadImage function to my code, I was able to login as a user successfully and print the user's email at the top of the page to prove they were actually signed in. Now that I have added the profile picture uploader code, when I log in as a user I get the following red screen error:

    LateInitializedError: Field 'imageUrl' has not been initialized.
    

    I have given the imageUrl the Late modifier thinking this would allow the code to run and have the variable assigned later in the run but that did not fix the issue. I need help letting the variable be okay with being null until the user can upload their own picture. Here's the video I was watching to learn how to start this process:

    Flutter Image Upload Tutorial

    Here's my code:

    import 'dart:io';
    import 'package:commentaries/net/authentication.dart';
    import 'package:commentaries/ui/nav.dart';
    import 'package:firebase_auth/firebase_auth.dart';
    import 'package:firebase_storage/firebase_storage.dart';
    import 'package:flutter/material.dart';
    import 'package:image_picker/image_picker.dart';
    import 'package:permission_handler/permission_handler.dart';
    
    class UserPage extends StatefulWidget {
      const UserPage({Key? key}) : super(key: key);
    
      @override
      _UserPageState createState() => _UserPageState();
    }
    
    class _UserPageState extends State<UserPage> {
      User user = auth.currentUser!;
      late String imageUrl; // A: USER PROFILE PICTURE
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('${user.email}'),
          ),
          body: Column(
            children: [
              (imageUrl != null)
                  ? Image.network(imageUrl)
                  : const Placeholder(
                      fallbackHeight: 200.0, fallbackWidth: double.infinity),
              const SizedBox(
                height: 20.0,
              ),
              ElevatedButton(
                child: const Text('Upload Image'),
                onPressed: () => uploadImage(),
              ),
              // A: LOGOUT USER HERE
              TextButton(
                child: const Text('Logout'),
                // this removes all previous routes and returns signed out user to the home tab (sign in screen)
                onPressed: () => signOut().then(
                  (_) => Navigator.of(context).pushAndRemoveUntil(
                      MaterialPageRoute(builder: (context) => const Nav()),
                      (Route<dynamic> route) => false),
                ),
                // onPressed:(){
                //   auth.signOut();
                //   Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => Nav()));
                // },
              ),
            ],
          ),
        );
      }
    
      uploadImage() async {
        final _storage = FirebaseStorage.instance;
        final _picker = ImagePicker();
        PickedFile image;
        // A: Check permissions
        await Permission.photos.request();
        var permissionStatus = await Permission.photos.status;
        if (permissionStatus.isGranted) {
          // A: Select Image
          // A: future picked file, add await clarification
          image = (await _picker.pickImage(source: ImageSource.gallery)) as PickedFile;
          var file = File(image.path);
          if (image != null) {
            // A: Upload to firebase
            var snapshot = await _storage
              .ref()
              .child('folderName/imageName') // will create folder: folderName and image: imageName
              .putFile(file);
            var downloadUrl = await snapshot.ref.getDownloadURL();
            setState(() {
              imageUrl = downloadUrl;
            });
          } else {
            print('No path recieved, no image detected');
          }
        } else {
          print('App is not permitted to access photo gallery');
        }
      }
    }
    
    • rickimaru
      rickimaru over 2 years
      Just change late String imageUrl to String? imageUrl.
    • Farid Shumbar
      Farid Shumbar over 2 years
      Hi @adamcapjones, did you have a chance to try what rickimaru suggested?
    • adamcapjones
      adamcapjones over 2 years
      Yes, this fixed my issue. Thank you, I was not aware of this as a feature