Home > database >  How to upload images in Firestore collection flutter
How to upload images in Firestore collection flutter

Time:06-04

I have a user profil form , and i want the profile image to be stored in firestore with the other infromation of the user ! I did the part of stocking the information but idon't know how to store the image in the same document! can you please help me ? My code can just pick the picture , i didn't integrate the part of storing it in firestore

const kTextFieldDecoration = InputDecoration(
  hintText: 'Enter a value',
  hintStyle: TextStyle(color: Colors.grey),
  contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
  border: OutlineInputBorder(
    borderRadius: BorderRadius.all(Radius.circular(32.0)),
  ),
  enabledBorder: OutlineInputBorder(
    borderSide: BorderSide(color: Color(0xff5AA7A7), width: 1.0),
    borderRadius: BorderRadius.all(Radius.circular(32.0)),
  ),
  focusedBorder: OutlineInputBorder(
    borderSide: BorderSide(color: Color(0xff5AA7A7), width: 2.0),
    borderRadius: BorderRadius.all(Radius.circular(32.0)),
  ),
);


class Background extends StatefulWidget {
   final Widget child;
   
  const Background({
    Key? key,
    required this.child,
  }) : super(key: key);
  @override
  _BackgroundState createState() => _BackgroundState();
}
class _BackgroundState extends State<Background>{
final _auth = FirebaseAuth.instance;
final _firebaseStorage = FirebaseStorage.instance ; 


uploadImage() async {
  Reference ref = _firebaseStorage.ref().child('profileimage');
  UploadTask uploadTask = ref.putFile(imageFile); 
  var imageUrl = await ( await uploadTask).ref.getDownloadURL();
  setState(() => {
     imageurl=  imageUrl.toString()
  });
}
 
  late File imageFile;
  late String name;
  late DateTime birth ; 
  late String pass ; 
  late String? genre ;
  
  TextEditingController dateinput = TextEditingController(); 
  
final List<String> genderItems = [
  'Male',
  'Female',
];
String? selectedValue;
  
  final ImagePicker _picker = ImagePicker();
  bool showSpinner = false;
 
  static final DateFormat format = DateFormat('yyyy-MM-dd');
  
  File? imagePicked;
  late Future<PickedFile?> pickedFile = Future.value(null);
  String? imageurl ; 




// Pick Image From Gallery
_getFromGallery() async {
    final picker = ImagePicker();
    final pickedImage = await picker.pickImage(
      source: ImageSource.gallery,
    );
    final pickedImageFile = File(pickedImage!.path);
    setState(() {
      imagePicked = pickedImageFile;
    });
  
}

 
  

    void addPatient() {
  FirebaseFirestore.instance.collection("patient").add(
  {
    
    "name" : name,
    "genre" : genre,
    "birth" : birth,
    "pass" : pass,
  }).then((value){
    print("Patient data Added");
    

  });
}
  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    
    return Scaffold(
      resizeToAvoidBottomInset: false ,
      backgroundColor: Colors.white,
      body: ModalProgressHUD(
        inAsyncCall: showSpinner,
       child: SingleChildScrollView(   
      child: Padding(
        
         padding: EdgeInsets.symmetric(horizontal: 24.0),
         child: Column(
            
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            
        children: <Widget>[
          

          Container(
            
            child : CircleAvatar(
            radius: 70.0,
            backgroundColor: Colors.grey,
            backgroundImage: imagePicked == null
                              ? null
                              : FileImage(
                                  imagePicked!,
                                ),
          ),
            
          ),
          
          Container(
            padding: EdgeInsets.only( left: 100.0),
                child : Positioned(
                        bottom: 50.0,
                        right: 20.0, 
                        
                        child: InkWell(
                          onTap: () {
                           _getFromGallery();
                              },
                        child: Icon(
                          Icons.camera_alt_outlined, 
                          size:28.0,color: 
                          Colors.teal,
                           ),
                            ),
                 ), ),
         
               SizedBox(
                height: 25.0,
              ),
              
               
               SizedBox(
                height: 8.0,
              ),
              TextField(
                  keyboardType: TextInputType.text,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    name = value;
                  },
                  decoration: kTextFieldDecoration.copyWith( 
                      labelText: 'Name')),
              SizedBox(
                height: 8.0,
              ),
              
              SizedBox(
                height: 8.0,
              ),
              TextField(
                  obscureText: true,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    pass = value ;
                  },
                  decoration: kTextFieldDecoration.copyWith(
                      labelText: 'Password',)),
                      SizedBox(
                height: 8.0,
              ),
              
              SizedBox(
                height: 8.0,
              ),
             Column(
               children: [
                   DropdownButtonFormField(
              decoration: 
                //Add isDense true and zero Padding.
                //Add Horizontal padding using buttonPadding and Vertical padding by increasing buttonHeight instead of add Padding here so that The whole TextField Button become clickable, and also the dropdown menu open under The whole TextField Button.
                InputDecoration(
          
         hintStyle: TextStyle(color: Colors.grey),
         contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
         border: OutlineInputBorder(
           borderRadius: BorderRadius.all(Radius.circular(32.0)),
         ),
         enabledBorder: OutlineInputBorder(
           borderSide: BorderSide(color: Color(0xff5AA7A7), width: 1.0),
           borderRadius: BorderRadius.all(Radius.circular(32.0)),
         ),
         focusedBorder: OutlineInputBorder(
           borderSide: BorderSide(color: Color(0xff5AA7A7), width: 2.0),
           borderRadius: BorderRadius.all(Radius.circular(32.0)),
         ),
                //Add more decoration as you want here
                //Add label If you want but add hint outside the decoration to be aligned in the button perfectly.
               labelText: 'Gender',

              ), 
                 isExpanded: true,
                 
                   
                   icon: const Icon(
                Icons.arrow_drop_down,
                color: Colors.teal,
              ), 
               iconSize: 30,
              
              items: genderItems
                      .map((item) =>
                      DropdownMenuItem<String>(
                        value: item,
                        child: Text(
                          item,
                          style: const TextStyle(
                            fontSize: 14,
                          ),
                        ),
                      ))
                      .toList(),
              validator: (value) {
                if (value == null) {
                  return 'Please select gender.';
                }
              },  
               onChanged: (value) {
                genre = value as String? ; //Do something when changing the item if you want.
              },
              onSaved: (value) {
                selectedValue = value.toString();
              },
            ),   
               ],
             ), 

                      SizedBox(
                height: 8.0,),
                      
              SizedBox(
                height: 8.0,
              ),
              TextField(
                       controller: dateinput,
                       textAlign: TextAlign.center,
                       readOnly: true,
                       
                       decoration: InputDecoration( 
                     
                    hintStyle: TextStyle(color: Colors.grey),
                 contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
                 border: OutlineInputBorder(
                   borderRadius: BorderRadius.all(Radius.circular(32.0)),
                 ),
                 enabledBorder: OutlineInputBorder(
                   borderSide: BorderSide(color: Color(0xff5AA7A7), width: 1.0),
                   borderRadius: BorderRadius.all(Radius.circular(32.0)),
                 ),
                 focusedBorder: OutlineInputBorder(
                   borderSide: BorderSide(color: Color(0xff5AA7A7), width: 2.0),
                   borderRadius: BorderRadius.all(Radius.circular(32.0)),
                 ),
                    //icon of text field
                  labelText: "Date of Birth" ,  //label text of field
               
               
                ), 

                  onTap: () => BottomPicker.date(
                  
                    minDateTime: DateTime(1900), 
                       maxDateTime: DateTime.now(), 
                       dateOrder: DatePickerDateOrder.dmy , 
                       bottomPickerTheme: BOTTOM_PICKER_THEME.morningSalad,
                       closeIconColor:  Colors.teal,
                       
                  title: "Set your Birthday",
                 titleStyle: const TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 15,
                    color: Colors.teal,
                 ),
                  onSubmit: (value) {
                   
                    dateinput.text = '$value'; 
                    birth = value ;
                    
                  } ,
                ).show(context),
              ),
 RoundedButton(
                colour: Color(0xff96D7C6),
                title: 'Submit',
                onPressed: () async {
                  setState(() {

                    showSpinner = true;
                    addPatient();
                  });
                  Navigator.pushNamed(context, 'patient_screen');
                }, ),],),),),),);}}

CodePudding user response:

You can use Firebase Storage ( firebase_storage ) to upload the image file and then you store the download url of the image inside the document in the Cloud Firestore ( cloud_firestore ).

Here is the official docs for using Firebase Storage with Flutter, Inside you can find a section that explains the steps to upload files, and another to get the download URL.

  • Related