Alan Book
Alan Book

Reputation: 81

Flutter: Upload image to Firestore using ImagePickerWeb

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

Answers (3)

OAlchemista
OAlchemista

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

Alan Book
Alan Book

Reputation: 81

With Flutter 2.0, the problem has been solved.

Upvotes: 0

SergeOin
SergeOin

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

Related Questions