Reputation: 81
I am trying to upload images in a Flutter web application to Firestore. The complete program is as below but not working. The error displayed is NoSuchMethodError: Method not found: 'buffer' on null. ImagePickerWeb does not return a full path so cannot use putFile(). Any suggestions how to solve the problem? Thanks!
import 'package:flutter/material.dart';
import 'values.dart';
import 'package:image_picker_web/image_picker_web.dart';
import 'dart:async';
import 'dart:ui' as ui;
import 'package:firebase_storage/firebase_storage.dart';
import 'dart:typed_data';
class MyHome extends StatefulWidget {
@override
_MyHomeState createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> {
Image pickedImage;
int width, height;
ByteData ImageData;
String errormsg = 'none';
@override
void initState() {
super.initState();
}
pickImage() async {
/// You can set the parameter asUint8List to true
/// to get only the bytes from the image
/* Uint8List bytesFromPicker =
await ImagePickerWeb.getImage(outputType: ImageType.bytes);
if (bytesFromPicker != null) {
debugPrint(bytesFromPicker.toString());
} */
/// Default behavior would be getting the Image.memory
Image fromPicker = await ImagePickerWeb.getImage(outputType: ImageType.widget);
Completer<ui.Image> completer = new Completer<ui.Image>();
fromPicker.image
.resolve(new ImageConfiguration())
.addListener(new ImageStreamListener((ImageInfo image, bool _) {
completer.complete(image.image);
}));
ui.Image info = await completer.future;
ImageData = await info.toByteData(format: ui.ImageByteFormat.png);
width = info.width;
height = info.height;
if (fromPicker != null) {
setState(() {
pickedImage = fromPicker;
});
}
}
uploadPhoto () async {
final storage = FirebaseStorage.instance;
bool hasError;
String imageURL;
errormsg = 'start';
if (pickedImage != null) {
try {
StorageReference firebaseStorageRef = await storage.ref().child(pickedImage.semanticLabel);
StorageUploadTask uploadTask = firebaseStorageRef.putData(ImageData.buffer.asUint8List());
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
imageURL = await taskSnapshot.ref.getDownloadURL();
}
catch (error) {
hasError = true;
errormsg = error.toString();
}
}
setState(() {
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Image Picker Web Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 300),
switchInCurve: Curves.easeIn,
child: SizedBox(
width: 200,
child: pickedImage,
) ??
Container(),
),
SizedBox(
width: 15,
),
],
),
(pickedImage != null) ? Text('$width x $height') : Text('0 x 0'),
ButtonBar(alignment: MainAxisAlignment.center, children: <Widget>[
RaisedButton(
onPressed: () => pickImage(),
child: Text('Select Image'),
),
RaisedButton(
onPressed: () => uploadPhoto(),
child: Text('Upload photo'),
),
]),
Text('Error: ' + errormsg),
])),
),
);
}
}
Upvotes: 1
Views: 792
Reputation: 46
putBlob is the solution to flutter web
FirebaseStorage storage = FirebaseStorage.instance;
Reference imageRef = storage.ref("images/profile/$nameImage.jpg");
if (kIsWeb) {
html.File? imagePicked = await ImagePickerWeb.getImageAsFile();
if (imagePicked != null) {
if (kDebugMode) {
print(imagePicked);
}
UploadTask uploadTask = imageRef.putBlob(imagePicked);
var urlDownload = await uploadTask
.whenComplete(() => imageRef.getDownloadURL());
String url = urlDownload.toString();
if (kDebugMode) {
print(url);
}
}
}
Upvotes: 0
Reputation: 11
Yo man i have same problem, but i use putBlob(),and my problem it's to put image path
import 'dart:html';
import 'package:chouette/config/Palette.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter_web_image_picker/flutter_web_image_picker.dart';
class AddComment extends StatefulWidget {
@override
_AddCommentState createState() => _AddCommentState();
}
class _AddCommentState extends State<AddComment> {
Image image;
File file;
String _myValue;
final formKey = new GlobalKey<FormState>();
FirebaseAuth auth = FirebaseAuth.instance;
var uri = Uri.base.path;
bool validateAndSave(){
final form = formKey.currentState;
if(form.validate()) {
form.save();
return true;
} else {
return false;
}
}
void uploadPhotoAndComment() async {
print(image);
if(validateAndSave()) {
FirebaseStorage commentRef = FirebaseStorage.instance;
var timeKey = new DateTime.now().toString();
var url = timeKey.toString();
final UploadTask uploadTask = commentRef.ref().child(url).putBlob(image);
var downloadUrl = await (await uploadTask).ref.getDownloadURL();
url = downloadUrl.toString();
gotoHome();
saveToDatabase(url);
}
}
void gotoHome() {
Navigator.pushNamed(context, '/home');
}
void saveToDatabase(url) {
var dbTimeKey = new DateTime.now();
var formatDate = new DateFormat('MMM d, yyyy');
var formatTime = new DateFormat('EEEE, hh:mm aaa');
String date = formatDate.format(dbTimeKey);
String time = formatTime.format(dbTimeKey);
final ref = FirebaseFirestore.instance;
var data = {
"user": auth.currentUser.uid,
"image": url,
"content": _myValue,
"uri": uri,
"date": date,
"time": time,
};
ref.collection("Posts").add(data);
}
void uploadImage({@required Function(File file) onSelected}) {
InputElement uploadInput = FileUploadInputElement()..accept = 'image/*';
uploadInput.click();
uploadInput.onChange.listen((event) {
final file = uploadInput.files.first;
final reader = FileReader();
reader.readAsDataUrl(file);
reader.onLoadEnd.listen((event) {
onSelected(file);
});
});
}
@override
Widget build(BuildContext context) {
WidgetsFlutterBinding.ensureInitialized();
Firebase.initializeApp();
return Scaffold(
appBar: AppBar(
title: Text("Ton Commentaire"),
backgroundColor: Palette.YowlBlue,
),
body: Container(
child: Column(
children: [
SizedBox(height: 100.0,),
Center(
child: Form(
key: formKey,
child: Column(
children: [
TextFormField(
decoration: new InputDecoration(labelText: 'Votre message'),
validator: (value){
return value.isEmpty ? 'Votre message est vide' : null;
},
onSaved: (value){
return _myValue = value;
},
),
SizedBox(height: 15.0,),
RaisedButton(
elevation: 10.0,
child: Text("Poster Commentaire"),
textColor: Colors.white,
color: Palette.YowlBlue,
//onPressed: uploadPhotoAndComment,
onPressed: () => uploadPhotoAndComment(),
),
],
),
),
),
SizedBox(height: 50.0,),
Center(
child: image != null ? image: Text('Pas image'),
),
],
),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Palette.YowlBlue,
child: Icon(Icons.add_a_photo, color: Colors.white,),
onPressed: () async {
await FlutterWebImagePicker.getImage.then((result) {
setState(() {
image = result;
});
});
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100.0),
),
),
);
}
}
Upvotes: 1