【问题标题】:flutter / dart error: The argument type 'Future<File>' can't be assigned to the parameter type 'File'颤振/飞镖错误:参数类型'Future<File>'不能分配给参数类型'File'
【发布时间】:2018-04-16 09:34:41
【问题描述】:

我正在尝试使用 Flutter 和 Firebase 构建我的第一个移动应用程序。 当我尝试显示和存储照片时,出现以下问题:

错误:不能将参数类型“Future”分配给参数类型“文件”。 (argument_type_not_assignable 在 [whereassistant] lib/main.dart:85)

我可能应该做一些演员,但我不明白如何正确地做。

这是我的未来文件声明:

Future<File> _imageFile;

我正在拍摄一张显示在屏幕上的照片:

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

但我在尝试将照片发送到 Firebase 时遇到错误:

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

这是我使用的基于代码示例的类:

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),
            ),
          ),
        ],
      ),
    );
  }
}

【问题讨论】:

    标签: firebase dart future flutter


    【解决方案1】:

    ref.put 要求File 作为参数。你传递的是Future&lt;File&gt;

    您需要等待未来的结果才能拨打电话。

    您可以将代码更改为

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

    或者将_imageFile改为File而不是Future&lt;File&gt;

    【讨论】:

      【解决方案2】:

      来自插件README.md

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

      ImagePicker.pickImage() 返回一个Future。您可以使用async/await,如上面代码所示,从Future获取值。

      【讨论】:

        【解决方案3】:

        对于那些仍在寻找答案的人,似乎同一个错误有不同的原因。就我而言,这是我作为参数传递给不同函数的文件的不同导入语句。在声明和定义的情况下,它应该是相同的文件(导入)。

        例如,不要在 dart 中这样使用

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

        然后在另一个类中

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

        因为

        在 Dart 中,两个库是相同的,当且仅当它们使用相同的 URI 导入。如果使用了两个不同的URI,即使解析到同一个文件,也会被认为是两个不同的库,文件内的类型会出现两次

        阅读更多here

        【讨论】:

        • 谢谢,您已经解决了这个问题:'import 'package:git_repo_flutter/..' 应该作为路径首选,尤其是在测试文件中
        【解决方案4】:

        要将Future&lt;File&gt; 转换为File,请在函数前添加await,使其参数成为Future 类型!

        File file2 = await fixExifRotation(imageFile.path);
        

        【讨论】:

          【解决方案5】:
          setState(() {
            _imageFile = ImagePicker.pickImage(source: source);
          });
          

          【讨论】:

          • 你不需要await吗?
          • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。您可以在帮助中心找到更多关于如何写好答案的信息:stackoverflow.com/help/how-to-answer。祝你好运?
          猜你喜欢
          • 2022-01-14
          • 2019-11-12
          • 1970-01-01
          • 2020-11-15
          • 1970-01-01
          • 2019-12-29
          • 1970-01-01
          • 2022-08-14
          • 2020-01-05
          相关资源
          最近更新 更多