Firebase Storage In Flutter

Introduction

Cloud storage allows you to store and manage user-generated content such as audio, images, and videos. It allows you to securely, quickly, and easily upload and download media from mobile devices and web browsers.

Cloud storage stores files in Google cloud storage bucket making them accessible through Firebase and Google Cloud. Using Firebase storage, you can build your app with rich media content despite the network quality.

Cloud Storage Key Capabilities

  • Robust operation
    Cloud Storage is a reliable storage as it performs uploads and downloads files regardless network quality. Uploads and downloads functions are robust which means the function will resume from where it stopped. This saves the user’s time and bandwidth.
  • Strong security
    Cloud storage provides simple and intuitive authentication for developers to ensure files security by integrating with Firebase Authentication. This integration allows access based on file type, size, content type and other metadata using declarative security model
  • High scalability
    Cloud storage is built to easily grow from prototype to production using the same infrastructure that powers Spotify and Google Photos. It is built for exabyte scale when your app goes viral.

Cloud Storage Setup and Configuration

There several steps that you need to take in order to set up Cloud storage and integrate with your Flutter app. These are quite simple and easy to follow steps so make sure to follow the instructions in this tutorial to get everything right.

1 Create Firebase Project

To begin with, you need to create a new Firebase project and set it up with the environment you’re working on. Take note that you don’t need to set up all environments (IOS, Android, Web).

2 Create Cloud Storage bucket

Next, you need to enable Cloud storage. To do so, in your console, click on storage in the left menu under the build section.

enable cloud storage

Next, click on get started and select the mode you want to start with. Production mode restrict user’s ability to manipulate the files stored in your cloud.

get started with storage
get started with storage
set up storage rules
set up storage rules

Then, select your storage location. Take note that once you set up the location you can’t change it later

set up storage location
set up storage location

3 Add Cloud Storage SDK to Flutter App

Now that you enabled cloud storage in the Firebase console, it’s time to add the cloud storage SDK to your Flutter app. You can achieve this by installing storage plugin and import it in Dart code.

There are two ways to install the plugin:

1. Run the following command in the root of your flutter project

flutter pub add firebase_storage

once complete, rebuild your flutter application using the run command

flutter run

2. Manually add the plugin link to your package’s pubspec.yaml file under the dependencies section. You can get the link from the packages of pub.dev site

firebase_storage:^10.3.11 
firebase_core: ^1.24.0

Once plugin is installed, you need to import it in your dart code

import 'package:firebase_storage/firebase_storage.dart';

4 Add File Picker Plugin

In addition to what we did in the previous steps, we also need to add a file picker plugin that allows us to pick a file from the device to upload it to firestore. This is an additional set up that is not required to get started with Cloud storage but it allows you to easily select files to upload to Firebase.

file_picker

As we’ve done in the previous step, run the following command in the root of your flutter project

flutter pub add file_picker
flutter run

or, alternatively, add the plugin link in the dependencies section in pubspec.yaml file

file_picker: ^5.2.1

lastly, import the plugin in your dart code

import 'package:file_picker/file_picker.dart';

Create Cloud Storage Reference on Flutter

In Firebase storage, files are stored in a hierarchical structure, just like the file system in your hard disk or the data in Realtime database. To access these files, you first need to create a reference so your app can get access to it. Later on, this reference can be used to upload, download , update, or delete a file. A reference can either points to a specific file, or to a higher level node in the hierarchy.

You can create a reference using the FirebaseStorage instance by calling the ref() method

final imagesRef = FirebaseStorage.instance.ref('images');

You can also create a reference to a lower location in the tree using the child() method on an existing reference

final childRef = storage.child('images/child.png')

Cloud Storage provides parent() and root() properties to navigate up in the file hierarchy. parent() property navigates up one level whereas root() property navigates all the way to the top.

final imagesRef2 = childRef.parent();

This upper code line will navigate to point back to images.

final rootRef = childRef.root();

This line of code will navigate to point to the top folder in the hierarchy.

Reference properties

  • name: This is the file name (ie.e child.png)
  • fullPath: file path on disk (i.e. images/child.png)
  • bucket: name of the storage bucket where the files are stored

Upload File to Firebase Storage in Flutter

Let’s create a new dart file to separate the cloud storage methods from the original code. This isn’t a necessary step but it helps keep your code clean and organized. In this file, storage_service.dart, we’ll be creating a class called StorageService. Inside this class, let’s create an instance of FirebaseStorage to get access to its various functions.

Once that’s done, we can now create our upload function which we’ll use to pick an image and upload it to the cloud. You can see how to upload image to Firebase storage Flutter from the code below:

import 'dart:io';
import 'package:firebase_core/firebase_core.dart' as firebase_core;
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
class StorageService {

  final firebase_storage.FirebaseStorage storage =
      firebase_storage.FirebaseStorage.instance;


  Future<void> uploadImage(String filePath, String fileName) async {
    File file = File(filePath);
    try {
      await storage.ref('images/$fileName').putFile(file);
    } on firebase_core.FirebaseException catch (e) {
      print(e);
    }

}}

Next, let’s implement the code we just wrote in the UI file. The first thing we need to do is to create a reference to the StorageService class which we just created inside the build() method.

final StorageService storage_service = StorageService();

Then, create a button that we’ll use to pick the file which we want to upload to the Firebase.

ElevatedButton(
    child: Text('Upload Image'),
    onPressed: () async {

      final result = await FilePicker.platform.pickFiles(
        allowMultiple: false,
        type: FileType.custom,
        allowedExtensions: ['png','jpg'],

      );

      if (result == null) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('No file has been selected'),)
        );

      }

      final path = result!.files.single.path;
      final fileName = result.files.single.name;

      storage_service.uploadImage(path!, fileName).then((value) =>
      print('Done'));


    },
  )

Download Files From Cloud Storage in Flutter

Cloud storage allows you to easily get files stored in the storage bucket using the getDownloadUrl() function. Let’s create another method in the storage_service.dart file which will return the image’s download URL which you can use to display.

Future<String> downloadUrl(String imageName) async{
    String downloadUrl = await storage.ref('images/$imageName').getDownloadURL();

    return downloadUrl;
}

Now, in the UI file, let’s create a FutureBuilder to display the returned image from the storage

FutureBuilder(
    future: storage_service.downloadUrl('img.jpg'), //image name here
    builder: (BuildContext context,
        AsyncSnapshot<String> snapshot) {

      if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
        return Container(
          width: 300,
          height: 250,
          child: Image.network(
            snapshot.data!,
            fit: BoxFit.cover,
          ),
        );
      }

      if (snapshot.connectionState == ConnectionState.waiting || !snapshot.hasData) {
        return CircularProgressIndicator();
      }

      return Container();
     
    }
),

Retrieve all Files from Cloud Storage in Flutter

You can get all the files stored in Firebase using the listResult method provided by Firebase Cloud store. In storage_service.dart file, create the following method:

Future<firebase_storage.ListResult> listFiles() async {
    firebase_storage.ListResult result = await storage.ref('images').listAll();
    result.items.forEach((firebase_storage.Reference ref) {
      print('Found File: $ref');
    });

    return result;

}

Then, let’s create another FutureBuilder that will display the names  of the retrieved files

FutureBuilder(
  future: storage_service.listFiles(),
     builder: (BuildContext context,
     AsyncSnapshot<firebase_storage.ListResult> snapshot) {

    if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
      return Container(
        height:40,
        padding: EdgeInsets.symmetric(horizontal: 20),
        child: ListView.builder(
          scrollDirection: Axis.horizontal,
          shrinkWrap: true,
          itemCount: snapshot.data!.items.length,
          itemBuilder: (BuildContext context, int index) {
            return Padding(
              padding: const EdgeInsets.symmetric(horizontal: 10.0),
              child: ElevatedButton(
                onPressed: () {},
                child: Text(snapshot.data!.items[index].name),
              ),
            );
          },


        ),
      );
    }

    if (snapshot.connectionState == ConnectionState.waiting && !snapshot.hasData) {
      return CircularProgressIndicator();
    }

    return Container();
     }
),

Delete Files from Cloud Storage in Flutter

You can delete a file from cloud storage by calling the delete() method on the reference to that specific file.

final toDeleteRef = FirebaseStorage.instance.ref('images/img.jpg');

then

await toDeleteRef.delete();

Common Cloud Storage Errors in Flutter

Error Description
storage/unknown An unknown error occurred.
storage/object-not-found No object exists at the desired reference.
storage/bucket-not-found No bucket is configured for Cloud Storage
storage/project-not-found No project is configured for Cloud Storage
storage/quota-exceeded Quota on your Cloud Storage bucket has been exceeded. If you’re on the no-cost tier, upgrade to a paid plan. If you’re on a paid plan, reach out to Firebase support.
storage/unauthenticated User is unauthenticated, please authenticate and try again.
storage/unauthorized User is not authorized to perform the desired action, check your security rules to ensure they are correct.
storage/retry-limit-exceeded The maximum time limit on an operation (upload, download, delete, etc.) has been excceded. Try uploading again.
storage/invalid-checksum File on the client does not match the checksum of the file received by the server. Try uploading again
storage/cancelled The user cancelled the operation
storage/invalid-event-name Invalid event name provided. Must be one of [running, progress, pause]
storage/invalid-url Invalid URL provided to refFromURL(). Must be of the form: gs://bucket/object or https://firebasestorage.googleapis.com/v0/b/bucket/o/object?token=<TOKEN>
storage/invalid-argument The argument passed to put() must be File, Blob, or UInt8 Array. The argument passed to putString() must be a raw, Base64, or Base64URL string.
storage/no-default-bucket in your storageBucket property, there is no bucket that has been set.
storage/cannot-slice-blob occurs when the local file has changed. Try uploading again after verifying the file hasn’t changed.
storage/server-file-wrong-size The file on the client doesn’t match the file received by the server, try again.
Common Cloud Storage Errors

Conclusion

This brings an end to our Firebase Storage in Flutter Tutorial. We learnt how to use firebase storage in flutter including setup, uploading, downloading, and deleting files. In addition, we learnt some of the very common errors that can arise when working with Cloud storage.

If you wish to learn more about Firebase, I have a whole category of Firebase that’s ripe for you to explore. You can learn about Firebase Email Authentication, mobile authentication, and Facebook authentication, Writing to Firestore.

Also, don’t forget to like and share my Facebook page, share the post with those who care to learn, and subscribe to my blog to be one of the firsts to know about my newest posts!

Thank you and happy coding!

Oh hi there!
It’s nice to meet you.

Sign up to receive awesome content in your inbox, every month.

Let's Do This!

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top