I am developing an app, and I want to create a user profile for each logged-in user. With my code now, I am able to get the user information from the cloud Firestore of each user uid document, but I want the user to be able to add an image to firebase storage, and then get this image, add to the specific user uid doc, and display on the app. Basically, I know how to get the data I have already, I just don't know how to update the user doc, especially with images.

Here is the code I have for the user profile:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:tradie_app/scr/providers/authService.dart';
import 'package:tradie_app/scr/screens/edit_company_email.dart';
import 'package:tradie_app/scr/widgets/loading.dart';

import 'home.dart';

class CompanyProfile extends StatefulWidget {
  @override
  _CompanyProfileState createState() => _CompanyProfileState();
}

class _CompanyProfileState extends State<CompanyProfile> {
  // Keep track of the form for validation
  final _formKey = GlobalKey<FormState>();

  // Loading Icon
  bool loading = false;

  final AuthService _authService = AuthService();
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
  final FirebaseFirestore _firebaseFirestore = FirebaseFirestore.instance;

  Future getCompanyNameData() async {
    final CollectionReference users =
        _firebaseFirestore.collection("Companies");
    final String uid = _firebaseAuth.currentUser.uid;
    final result = await users.doc(uid).get();
    return result.data()["companyName"];
  }

  Future getCompanyEmailData() async {
    final CollectionReference users =
        _firebaseFirestore.collection("Companies");
    final String uid = _firebaseAuth.currentUser.uid;
    final result = await users.doc(uid).get();
    return result.data()["companyEmail"];
  }

  @override
  Widget build(BuildContext context) {
    return loading
        ? Loading()
        : Scaffold(
            backgroundColor: Colors.white,
            appBar: AppBar(
              iconTheme: IconThemeData(color: Colors.black),
              backgroundColor: Colors.white,
              title: Text(
                "Create the company profile",
                style: TextStyle(
                  color: Colors.black,
                ),
              ),
              elevation: 0.0,
            ),
            drawer: Drawer(
              child: ListView(
                padding: EdgeInsets.zero,
                children: <Widget>[
                  UserAccountsDrawerHeader(
                    accountName: FutureBuilder(
                      future: getCompanyNameData(),
                      builder: (_, AsyncSnapshot snapshot) {
                        if (snapshot.connectionState ==
                            ConnectionState.waiting) {
                          return Text("Loading");
                        }
                        return Text(snapshot.data);
                      },
                    ),
                  ),
                  ListTile(
                    leading: Icon(Icons.logout),
                    title: Text(
                      "Log Out",
                    ),
                    onTap: () async {
                      await _authService.signOut();
                    },
                  ),
                ],
              ),
            ),
            body: Padding(
              padding: const EdgeInsets.all(18.0),
              child: SingleChildScrollView(
                child: Container(
                  child: Form(
                    key: _formKey,
                    child: Column(
                      children: [
                        Row(
                          children: [
                            Text(
                              "Company name: ",
                              style: TextStyle(
                                color: Colors.black,
                                fontSize: 20.0,
                              ),
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 10.0,
                        ),
                        Row(
                          children: [
                            FutureBuilder(
                              future: getCompanyNameData(),
                              builder: (_, AsyncSnapshot snapshot) {
                                if (snapshot.connectionState ==
                                    ConnectionState.waiting) {
                                  return Text("Loading");
                                }
                                return Text(
                                  snapshot.data,
                                  style: TextStyle(
                                      color: Colors.black, fontSize: 15.0),
                                );
                              },
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 20.0,
                        ),
                        Row(
                          children: [
                            Text(
                              "Company email: ",
                              style: TextStyle(
                                color: Colors.black,
                                fontSize: 20.0,
                              ),
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 10.0,
                        ),
                        Row(
                          children: [
                            FutureBuilder(
                              future: getCompanyEmailData(),
                              builder: (_, AsyncSnapshot snapshot) {
                                if (snapshot.connectionState ==
                                    ConnectionState.waiting) {
                                  return Text("Loading");
                                }
                                return Text(
                                  snapshot.data,
                                  style: TextStyle(
                                    color: Colors.black,
                                    fontSize: 15.0,
                                  ),
                                );
                              },
                            ),
                            IconButton(
                              icon: Icon(Icons.edit),
                              onPressed: () => Navigator.of(context).push(
                                MaterialPageRoute(
                                  builder: (context) =>
                                      EditCompanyEmailScreen(),
                                ),
                              ),
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 20.0,
                        ),
                        Row(
                          children: [
                            Text(
                              "Company phone number: ",
                              style: TextStyle(
                                color: Colors.black,
                                fontSize: 20.0,
                              ),
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 20.0,
                        ),
                        // Here is where I want to add the image
                        Row(
                          children: <Widget>[],
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          );
  }
}


Solution 1: Ganesh Bhat

You need to upload the image chosen from gallery to your firebase storage and then use the url in your firestore.

here is a samle code to upload the image to storage

import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;

final ref = firebase_storage.FirebaseStorage.instance.ref().child("profile-pic/abc.jpg");

final imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);

final uploadTask = ref.putFile(imageFile);
final snapshot = await uploadTask.whenComplete(() => null);
imageUrl = await snapshot.ref.getDownloadURL();

use the imageUrl and update it in your firestore collection for the user. You can fetch the url and display image whenever you need.


Solution 2: Deepak Lohmod

To select the image from gallery add this plugin. And then call this function to select the image.

File _image;
    selectImageFromGallery() async
          {
            final picker=ImagePicker();
            setState(() {
              inProcess=true;
            });
            final imageFile= await picker.getImage(source: ImageSource.gallery);
            if(imageFile!=null)
            {
              _image=File(imageFile.path);
            }
            setState(() {
              inProcess=false;
            });
          }

after selecting the image run this function to store image to firebase and get url of the image.

Future<String> uploadFile(File image) async
  {
    String downloadURL;
    String postId=DateTime.now().millisecondsSinceEpoch.toString();
    Reference ref = FirebaseStorage.instance.ref().child("images").child("post_$postId.jpg");
    await ref.putFile(image);
    downloadURL = await ref.getDownloadURL();
    return downloadURL;
  }

now lets upload and update data in firestore docs and storage.

uploadToFirebase()async
{
String url=await uploadFile(_image); // this will upload the file and store url in the variable 'url'
await users.doc(uid).update({  //use update to update the doc fields.
'url':url
});
}

To show the selected image add this in your Ui:-

Container(
          height: 200,
          width: 200,
          decoration: BoxDecoration(image: DecorationImage(image: FileImage(_image,),fit: BoxFit.contain)),
        )

After adding this image make a button for upload:-

RaisedButton()
{
  onPressed:(){
     uploadToFirebase();
  },
  child:Text("Upload"),
}

After selecting the image user will click on this button to upload and save sata to firebase.