(Flutter Web) Firebase Storage not working with firebase plugin

Viewed 3622

I've recently added Flutter Web support for one of my projects which heavily uses Firebase services. Everything seems to work fine except Firebase Storage which doesn't work. I know that firebase_storage plugin currently doesn't work with Web so I tried instead with the regular firebase plugin but I can't get it to work.

I sometimes get different "red screen"-errors, but everything is related to pages which uses Firebase Storage. Here is one example of a red screen:

enter image description here

Here are the 3 files in which I previously used firebase_storage with success (Android) and with the code that I tried to get to work with th firebase plugin.

import 'package:firebase/firebase.dart' as fb;

// artiklar/images
final fb.StorageReference fbRefArtiklarImages =
    fb.app().storage().ref().child("artiklar").child("images");

// guider/categoryImages
final fb.StorageReference fbRefGuiderCategoryImages =
    fb.app().storage().ref().child("guider").child("categoryImages");
// guider/guideImages
final fb.StorageReference fbRefGuiderGuideImages =
    fb.app().storage().ref().child("guider").child("guideImages");

// kalender/images
final fb.StorageReference fbRefKalenderImages =
    fb.app().storage().ref().child("kalender").child("images");

// sidor/sidloggor
final fb.StorageReference fbRefSidorSidloggorImages =
    fb.app().storage().ref().child("sidor").child("sidloggor");
// sidor/sidcovers
final fb.StorageReference fbRefSidorSidcoversImages =
    fb.app().storage().ref().child("sidor").child("sidcovers");
// sidor/postImages/:sidaID/
final fb.StorageReference fbRefSidorPostImagesImages =
    fb.app().storage().ref().child("sidor").child("postImages");
// sidor/postImages/:sidaID/
final fb.StorageReference fbRefSidorKalenderImagesImages =
    fb.app().storage().ref().child("sidor").child("kalenderImages");

-

import 'dart:io';
import 'package:firebase/firebase.dart' as fb;

class StorageService {
  //STORAGE REFERENCES
  final fb.Storage _storage = fb.app().storage("gs://astoria-site.appspot.com");

  //UPLOADS IMAGE TO FIREBASE
  fb.UploadTask _uploadTask;

  Future<void> uploadStorageImage(File imageFile, String filePath) async {
    _uploadTask = _storage.ref().child(filePath).put(imageFile);
    return;
  }

  //DELETES IMAGE IN FIREBASE
  Future<void> deleteStorageImage(String filePath) async {
    try {
      await _storage.ref().child(filePath).delete();
    } catch (e) {
      print(e.toString());
    }

    return;
  }
}

-

import 'package:astoria/theme/colors.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:firebase/firebase.dart';
import 'package:flutter/material.dart';

class FirebaseStorageImage extends StatelessWidget {
  final String fileName;
  final StorageReference storageLocation;

  FirebaseStorageImage({
    @required this.fileName,
    @required this.storageLocation,
  });

  Future<String> _getImageURL() async {
    final StorageReference ref = storageLocation.child(fileName + ".jpg");

    try {
      var url = await ref.getDownloadURL();
      return url.toString();
    } catch (e) {
      return null;
    }
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _getImageURL(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done &&
            snapshot.hasData) {
          return Image(
            image: CachedNetworkImageProvider(snapshot.data),
            fit: BoxFit.cover,
          );
        } else if (snapshot.connectionState == ConnectionState.waiting) {
          //RETURN THIS WHILE WAITING FOR IMAGE
          return Container(color: lightGreyColor);
        } else {
          //RETURN THIS IF NO IMAGE WAS FOUND AT THAT LOCATION
          return Image(
            image: AssetImage("assets/images/placeholder.png"),
            fit: BoxFit.cover,
          );
        }
      },
    );
  }
}
2 Answers

You need to pass a string to the ref method for it to work. For ease, change ref to refFromURL, then pass your bucket URL as a string to it as follows;

fb.app().storage().refFromURL("YOUR BUCKET URL HERE eg: 'gs://project-ID.appspot.com'")

Then you can safely add the remaining methods to it, such as; child() then put() or putString(). Goodluck!!!

For those coming after me, here's a summary of achieving Firebase Storage image download for Flutter Web.

Thanks to Learn Flutter Code for this nice little tutorial.

Don't make Firebase Storage a dependency, just Firebase with:

import 'package:firebase/firebase.dart' as fb;

Then create a method:

        Future<Uri> myDownloadURL() async {return await fb.storage().refFromURL('gs://<your storage reference>').child('$id.jpg').getDownloadURL();}

Call it from a FutureBuilder like so:

        FutureBuilder<Uri>(
        future: myDownloadURL(),
        builder: (context, AsyncSnapshot<dynamic> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return <Something as a placeholder>;
          }
          return CircleAvatar(
            radius: backgroundRadius * 2,
            child: Image.network(snapshot.data.toString()),
          );
        },
      )
Related