Flutter Firebase Image & File Upload CRUD

Flutter Firebase Image & File Upload CRUD

    Previously we did Flutter Firebase CRUD for text information. Flutter firebase image and file upload we will use three plugins. 


    First create a project and then install the above three plugins.


    Android settings

    Android doesn't need much settings. Just in AndroidManifest.xml file do the follow



    iOS settings

    iOS setting is also relatively easy. Just put the code in the Info.plist right after first <dict>

    <string>Some Description</string>
    <string>Some Description</string>
    <string>Some Description</string>

    Warnings: iOS simulator on Mac M1 chip doesn't support a stable image_picker plugin.

    Core functions

    await picker.pickImage()

    await storage.ref(fileName).putFile()

    Complete code

    // main.dart
    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    import 'dart:io';
    import 'package:firebase_core/firebase_core.dart';
    import 'package:firebase_storage/firebase_storage.dart';
    import 'package:path/path.dart' as path;
    import 'package:image_picker/image_picker.dart';
    void main() async {
      // Initialize a new Firebase App instance
      await Firebase.initializeApp();
      runApp(const MyApp());
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
      Widget build(BuildContext context) {
        return MaterialApp(
          // Remove the debug banner
          debugShowCheckedModeBanner: false,
          title: 'dbestech',
          theme: ThemeData(primarySwatch: Colors.green),
          home: const HomePage(),
    class HomePage extends StatefulWidget {
      const HomePage({Key? key}) : super(key: key);
      _HomePageState createState() => _HomePageState();
    class _HomePageState extends State<HomePage> {
      FirebaseStorage storage = FirebaseStorage.instance;
      // Select and image from the gallery or take a picture with the camera
      // Then upload to Firebase Storage
      Future<void> _upload(String inputSource) async {
        final picker = ImagePicker();
        XFile? pickedImage;
        try {
          pickedImage = await picker.pickImage(
              source: inputSource == 'camera'
                  ? ImageSource.camera
                  : ImageSource.gallery,
              maxWidth: 1920);
          final String fileName = path.basename(pickedImage!.path);
          File imageFile = File(pickedImage.path);
          try {
            // Uploading the selected image with some custom meta data
            await storage.ref(fileName).putFile(
                SettableMetadata(customMetadata: {
                  'uploaded_by': 'learners',
                  'description': 'learning the hacks'
            // Refresh the UI
            setState(() {});
          } on FirebaseException catch (error) {
            if (kDebugMode) {
        } catch (err) {
          if (kDebugMode) {
      // Retriew the uploaded images
      // This function is called when the app launches for the first time or when an image is uploaded or deleted
      Future<List<Map<String, dynamic>>> _loadImages() async {
        List<Map<String, dynamic>> files = [];
        final ListResult result = await storage.ref().list();
        final List<Reference> allFiles = result.items;
        await Future.forEach<Reference>(allFiles, (file) async {
          final String fileUrl = await file.getDownloadURL();
          final FullMetadata fileMeta = await file.getMetadata();
            "url": fileUrl,
            "path": file.fullPath,
            "uploaded_by": fileMeta.customMetadata?['uploaded_by'] ?? 'Nobody',
                fileMeta.customMetadata?['description'] ?? 'No description'
        return files;
      // Delete the selected image
      // This function is called when a trash icon is pressed
      Future<void> _delete(String ref) async {
        await storage.ref(ref).delete();
        // Rebuild the UI
        setState(() {});
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('dbestech),
          body: Padding(
            padding: const EdgeInsets.all(20),
            child: Column(
              children: [
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: [
                        onPressed: () => _upload('camera'),
                        icon: const Icon(Icons.camera),
                        label: const Text('camera')),
                        onPressed: () => _upload('gallery'),
                        icon: const Icon(Icons.library_add),
                        label: const Text('Gallery')),
                  child: FutureBuilder(
                    future: _loadImages(),
                    builder: (context,
                        AsyncSnapshot<List<Map<String, dynamic>>> snapshot) {
                      if (snapshot.connectionState == ConnectionState.done) {
                        return ListView.builder(
                          itemCount: snapshot.data?.length ?? 0,
                          itemBuilder: (context, index) {
                            final Map<String, dynamic> image =
                            return Card(
                              margin: const EdgeInsets.symmetric(vertical: 10),
                              child: ListTile(
                                dense: false,
                                leading: Image.network(image['url']),
                                title: Text(image['uploaded_by']),
                                subtitle: Text(image['description']),
                                trailing: IconButton(
                                  onPressed: () => _delete(image['path']),
                                  icon: const Icon(
                                    color: Colors.red,
                      return const Center(
                        child: CircularProgressIndicator(),


    Recommended posts

    Recent posts