web-dev-qa-db-fra.com

erreur Flutter/Dart: le type d'argument 'Future <File>' ne peut pas être affecté au type de paramètre 'File'

J'essaie de créer ma première application mobile avec Flutter et Firebase . Lorsque j'essaie d'afficher et de stocker une photo, j'ai le problème suivant: 

erreur: le type d'argument 'Future' ne peut pas être affecté au type de paramètre 'Fichier'. (argument_type_not_assignable at [Whilesistant] lib/main.Dart: 85)

Je devrais probablement faire un casting mais je ne comprends pas comment le faire correctement.

Voici ma déclaration de fichier Future: 

Future<File> _imageFile;

Je prends une photo qui est affichée à l'écran: 

    setState(() {
      _imageFile = ImagePicker.pickImage(source: source);
    });

Mais j'ai l'erreur en essayant d'envoyer la photo à Firebase: 

    final StorageUploadTask uploadTask = ref.put(_imageFile);
    final Uri downloadUrl = (await uploadTask.future).downloadUrl;

Voici la classe que j'utilise basée sur un exemple de code:

class _MyHomePageState extends State<MyHomePage> {
  Future<File> _imageFile;

  void _onImageButtonPressed(ImageSource source) async {
    GoogleSignIn _googleSignIn = new GoogleSignIn();
    var account = await _googleSignIn.signIn();
    final GoogleSignInAuthentication googleAuth = await account.authentication;
    final FirebaseUser user = await _auth.signInWithGoogle(
      accessToken: googleAuth.accessToken,
      idToken: googleAuth.idToken,
    );
    assert(user.email != null);
    assert(user.displayName != null);
    assert(!user.isAnonymous);
    assert(await user.getIdToken() != null);

    final FirebaseUser currentUser = await _auth.currentUser();
    assert(user.uid == currentUser.uid);

    setState(() {
      _imageFile = ImagePicker.pickImage(source: source);
    });
    var random = new Random().nextInt(10000);
    var ref = FirebaseStorage.instance.ref().child('image_$random.jpg');
    final StorageUploadTask uploadTask = ref.put(_imageFile);
    final Uri downloadUrl = (await uploadTask.future).downloadUrl;
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: const Text('Where Assistant'),
      ),
      body: new Center(
        child: new FutureBuilder<File>(
          future: _imageFile,
          builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
            debugPrint('test recup image');
            print(snapshot);

            if (snapshot.connectionState == ConnectionState.done &&
                snapshot.data != null) {
              return new Image.file(snapshot.data);
            } else if (snapshot.error != null) {
              return const Text('Error picking image.');
            } else {
              return const Text('No image so far.');
            }
          },
        ),
      ),
      floatingActionButton: new Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          new FloatingActionButton(
            onPressed: () => _onImageButtonPressed(ImageSource.gallery),
            tooltip: 'Pick an image from gallery',
            child: new Icon(Icons.photo_library),
          ),
          new Padding(
            padding: const EdgeInsets.only(top: 16.0),
            child: new FloatingActionButton(
              onPressed: () => _onImageButtonPressed(ImageSource.camera),
              tooltip: 'Take a Photo',
              child: new Icon(Icons.camera_alt),
            ),
          ),
        ],
      ),
    );
  }
}
5
hawkbee

ref.put demande une File comme paramètre. Ce que vous passez est un Future<File>

Vous devez attendre le résultat de cet avenir pour passer votre appel.

Vous pouvez changer votre code pour

final StorageUploadTask uploadTask = ref.put(await _imageFile);
final Uri downloadUrl = (await uploadTask.future).downloadUrl;

Ou remplacez _imageFile par File au lieu de Future<File>

5
Rémi Rousselet

Pour ceux qui cherchent encore des réponses, il semble qu'il y ait différentes raisons à la même erreur. Dans mon cas, c’était la déclaration d’importation différente d’un fichier que je transmettais comme paramètres à une fonction différente. Il devrait s'agir du même fichier (importation) en cas de déclaration et de définition. 

par exemple, n'utilise pas comme ceci dans Dart:

import 'GitRepoResponse.Dart';
import 'GitRowItem.Dart';

puis dans une autre classe 

import 'package:git_repo_flutter/GitRepoResponse.Dart';
import 'package:git_repo_flutter/GitRowItem.Dart';

parce que

Dans Dart, deux bibliothèques sont identiques si, et seulement si, elles sont importées en utilisant le même URI. Si deux adresses URI différentes sont utilisées, même si elles aboutissent au même fichier, elles seront considérées comme deux bibliothèques différentes et les types dans le fichier se produiront deux fois.

En savoir plus ici

1
vikas kumar

Depuis le plugin README.md

  Future getImage() async {
    var image = await ImagePicker.pickImage(source: ImageSource.camera);

    setState(() {
      _image = image;
    });
  }

ImagePicker.pickImage() renvoie Future. Vous pouvez utiliser async/await comme indiqué dans le code ci-dessus pour obtenir la valeur de Future.

1
Günter Zöchbauer