flutter / dart error: The argument type 'Future<File>' can't be assigned to the parameter type 'File'

53,205

Solution 1

ref.put asks for a File as parameter. What you are passing is a Future<File>.

You need to wait for the result of that future to make your call.

You can change your code to

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

Or change _imageFile to File instead of Future<File>

Solution 2

From the plugin README.md

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

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

ImagePicker.pickImage() returns a Future. You can use async/await like shown in the code above the get the value from the Future.

Solution 3

For those who are still looking for answers, as it seems there are different reasons for the same error. In my case, it was the different import statement for a file which I was passing as parameters to a different function. It should be same file(import) in case of declaration and definition.

for example, don't use like this in dart:

import 'GitRepoResponse.dart';
import 'GitRowItem.dart';

and then in some another class

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

because

In Dart, two libraries are the same if, and only if, they are imported using the same URI. If two different URIs are used, even if they resolve to the same file, they will be considered to be two different libraries and the types within the file will occur twice

Read more here

Share:
53,205
hawkbee
Author by

hawkbee

I'd like to work remotely as part of a flutter team. Email: googandads [AT] gmail [DOT] com

Updated on November 01, 2021

Comments

  • hawkbee
    hawkbee over 2 years

    I'm trying to build my first mobile application with flutter and firebase. When I try to display and store a photo I have the following issue :

    error: The argument type 'Future' can't be assigned to the parameter type 'File'. (argument_type_not_assignable at [whereassistant] lib/main.dart:85)

    I should probably do some casting but I don't understand hox to do it properly.

    Here's my Future file declaration :

    Future<File> _imageFile;
    

    I'm taking a Photo which is displayed on screen :

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

    But I have the error when trying to send the photo to Firebase :

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

    Here's the class I'm using based on a code example :

    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),
                ),
              ),
            ],
          ),
        );
      }
    }
    
  • Alessandro Ornano
    Alessandro Ornano over 5 years
    Thank you, you have centered the issue: 'import 'package:git_repo_flutter/..' should be preferred as path, especially in testing files
  • Jeremy Caney
    Jeremy Caney over 2 years
    Wouldn’t you need an await?
  • nima
    nima over 2 years
    While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. You can find more information on how to write good answers in the help center: stackoverflow.com/help/how-to-answer . Good luck 🙂