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