flutter / dart错误:参数类型&#39; Future <file>&#39;无法分配到参数类型&#39;文件&#39;

时间:2018-04-16 09:34:42

标签: firebase dart future flutter

我试图使用flutter和firebase构建我的第一个移动应用程序。 当我尝试显示和存储照片时,我遇到以下问题:

  

错误:参数类型&#39;未来&#39;无法分配到参数类型&#39;文件&#39;。 (argument_type_not_assignable在[whereassistant] lib / main.dart:85)

我应该做一些演员,但我不明白hox要做得好。

这是我的未来文件声明:

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

4 个答案:

答案 0 :(得分:7)

ref.put要求File作为参数。你传递的是Future<File>

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

您可以将代码更改为

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

或者将_imageFile更改为File而不是Future<File>

答案 1 :(得分:2)

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

例如,不要在飞镖中使用这样的

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

然后在另一个班级

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

因为

  

在Dart中,当且仅当使用相同的URI导入它们时,两个库才是相同的。如果使用两个不同的URI,即使它们解析为同一文件,也将被视为两个不同的库,并且文件中的类型将出现两次

了解更多here

答案 2 :(得分:1)

来自插件README.md

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

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

ImagePicker.pickImage()返回Future。您可以使用上面代码中显示的async / await获取Future中的值。

答案 3 :(得分:0)

要将Future<File>转换为File,请在函数前面添加await,以使其参数成为Future类型!

File file2 = await fixExifRotation(imageFile.path);