Gokul Shivappa ๐Ÿš€
 ยท Your go-to FlutterFlow partner.

๐Ÿ“ธ Uploading Images to Specific Firebase Storage Bucket in FlutterFlow ๐Ÿš€

Upload Image action Code [more web focused] (Check Below for Mobile Focused code)

Don't need to use FlutterFlow upload action you can directly implement this action

import 'dart:typed_data';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;
import 'dart:html' as html;

Future<String> uploadImage(String storagePath) async {
  if (storagePath.isEmpty) {
    throw ArgumentError("storagePath must be provided.");
  }

  if (Firebase.apps.isEmpty) {
    await Firebase.initializeApp();
  }

  Uint8List? imageData;
  String fileName;
  String mimeType;

  if (kIsWeb) {
    // Web platform
    html.File? pickedFile = await _pickImageWeb();
    if (pickedFile == null) {
      throw Exception("No image was selected.");
    }

    imageData = await pickedFile.readAsBytes();
    fileName = pickedFile.name;
    mimeType = pickedFile.type;
  } else {
    // Mobile platform
    final ImagePicker picker = ImagePicker();
    final XFile? imageFile =
        await picker.pickImage(source: ImageSource.gallery);

    if (imageFile == null) {
      throw Exception("No image was selected.");
    }

    imageData = await imageFile.readAsBytes();
    fileName = path.basename(imageFile.path);
    mimeType = 'image/' + path.extension(imageFile.path).replaceAll('.', '');
  }

  // Extract the bucket name and path from the storagePath
  Uri storageUri = Uri.parse(storagePath);
  String bucketName = storageUri.authority;
  String fullPath = storageUri.path + '/' + fileName;

  // Create a reference to the storage bucket
  FirebaseStorage storage =
      FirebaseStorage.instanceFor(bucket: 'gs://$bucketName');
  Reference storageReference = storage.ref().child(fullPath);

  // Create metadata for the upload
  SettableMetadata metadata = SettableMetadata(contentType: mimeType);

  // Upload the file with metadata
  UploadTask uploadTask = storageReference.putData(imageData, metadata);
  TaskSnapshot taskSnapshot = await uploadTask;

  // Get and return the download URL
  String downloadURL = await taskSnapshot.ref.getDownloadURL();
  return downloadURL;
}

Future<html.File?> _pickImageWeb() async {
  html.FileUploadInputElement uploadInput = html.FileUploadInputElement();
  uploadInput.click();

  await uploadInput.onChange.first;
  if (uploadInput.files!.isEmpty) return null;
  return uploadInput.files!.first;
}

extension on html.File {
  Future<Uint8List> readAsBytes() async {
    final reader = html.FileReader();
    reader.readAsArrayBuffer(this);
    await reader.onLoadEnd.first;
    return reader.result as Uint8List;
  }
}

Mobile focused Code:

import 'dart:typed_data';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;

Future<String> uploadImage(String storagePath) async {
  if (storagePath.isEmpty) {
    throw ArgumentError("storagePath must be provided.");
  }

  if (Firebase.apps.isEmpty) {
    await Firebase.initializeApp();
  }

  Uint8List? imageData;
  String fileName;
  String mimeType;

  // Mobile platform
  final ImagePicker picker = ImagePicker();
  final XFile? imageFile = await picker.pickImage(source: ImageSource.gallery);

  if (imageFile == null) {
    throw Exception("No image was selected.");
  }

  imageData = await imageFile.readAsBytes();
  fileName = path.basename(imageFile.path);
  mimeType = 'image/' + path.extension(imageFile.path).replaceAll('.', '');

  // Extract the bucket name and path from the storagePath
  Uri storageUri = Uri.parse(storagePath);
  String bucketName = storageUri.authority;
  String fullPath = storageUri.path + '/' + fileName;

  // Create a reference to the storage bucket
  FirebaseStorage storage =
      FirebaseStorage.instanceFor(bucket: 'gs://$bucketName');
  Reference storageReference = storage.ref().child(fullPath);

  // Create metadata for the upload
  SettableMetadata metadata = SettableMetadata(contentType: mimeType);

  // Upload the file with metadata
  UploadTask uploadTask = storageReference.putData(imageData, metadata);
  TaskSnapshot taskSnapshot = await uploadTask;

  // Get and return the download URL
  String downloadURL = await taskSnapshot.ref.getDownloadURL();
  return downloadURL;
}

Refer the image below for Action Settings:

Copy the Storage bucket path and pass it in the action parameter "storagepath":

Storage Rules to avoid errors:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

10
6 replies