How to upload to Firebase Storage with Flutter

This is the second part of our tutorial series on how to upload images to Firebase Storage using the Flutter app. Click here for part one.

In this shot, we are going to deal with UI as well as functionality. The idea is to create a simple interface containing an image display container and a button to upload an image after selecting it from the gallery. After an image is selected, the file will be automatically uploaded to the Firebase storage and then displayed on the screen.

Implementing image upload in a Flutter project

In order to use Firebase services and access the device gallery, we need to make use of some library packages. The list of plugins to be included are provided in the code snippet below:

firebase_core: ^0.4.5
image_picker: ^0.6.7+14
firebase_storage: ^3.1.6
permission_handler: ^5.0.1+1

Here, we have four plugins:

firebase_core: This is a core Firebase package that allows us to bind Firebase services to Flutter projects and use the service modules.

image_picker: This package offers modules access to the device gallery to select an image.

firebase_storage: This package offers Firebase storage service modules to be used in Flutter. The methods offered will allow us to configure the uploading feature.

permission_handler: This package allows us to handle the permission to our storage. It provides a simple interface to control the access to a users’ device permissions.

We need to copy these plugins, paste them into the pubspec.yaml file, and save it to install them. We can also run the following command to get them installed:

flutter get packages

After installation, we can import the packages to the main.dart file as directed in the code snippet below:

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';

Next, we need to create a new stateful widget class called ImageUpload in the main.dart file as shown in the code snippet below:

class ImageUpload extends StatefulWidget {
  @override
  _ImageUploadState createState() => _ImageUploadState();
}

class _ImageUploadState extends State<ImageUpload> {
  String imageUrl;

  @override
  Widget build(BuildContext context) {
    backgroundColor: Colors.white,
    return Scaffold(  
      appBar: AppBar(
        title: Text('Upload Image', style: TextStyle(color: Colors.black87, fontWeight: FontWeight.bold),),
        centerTitle: true,
        elevation: 0.0,
        backgroundColor: Colors.white,
      ),
      body: Container()
   );
  }
}

In the widget builder function, we have returned a Scaffold widget with a AppBar and an empty Container as a body property.

Now, we need to call the class object in the MyApp stateless class object as shown below:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: ImageUpload(),
    );
  }
}

If we run the app using the command flutter run, we will get the following result in our device or emulator:
Let’s get started!