Flutter firebase setData()函数在完成异步函数之前将空值分配给字段

Posted

技术标签:

【中文标题】Flutter firebase setData()函数在完成异步函数之前将空值分配给字段【英文标题】:Flutter firebase setData() function assigns null value to a field before completion of an async function 【发布时间】:2020-11-03 03:23:38 【问题描述】:

我正在尝试将用户的头像上传到 Firestore 存储并返回图像 url 以将其保存到用户实例上的用户 avatarUrl 属性。我能够成功地将图像上传到 Firestore。问题与网址的接收有关。异步函数会延迟,因此前面的用户实例化函数会使用 avatarUrl 属性的空值。

这里是函数初始化

                    if(_formKey.currentState.validate())
                      setState(() 
                        loading=true;
                      );
                      await uploadFile();
                      print('Print before async function complete...');
                      print(_avatarUrl);
                      dynamic result=  await SellerDatabaseService(uid:user.uid).sellerProfileSetup(
                        shopName: shopName,
                        phone: phone,
                        bio: bio,
                        location: location,
                        avatarUrl: _avatarUrl,
                        rating: 0,
                        sales: 0,
                        credit: 0,
                        posts: 0,
                        joinedDate:DateTime.now(),
                        //todo remove null from profile image
                      );
                      if(result==null)
                        setState(() 
                          loading=false;
                          error='Please supply correct details';
                        );
                      
                    
                  ,

这里是上传功能

 String _avatarUrl;
  Future uploadFile() async 
    StorageReference storageReference = FirebaseStorage.instance
        .ref()
        .child('avatars/$_image.path');
    StorageUploadTask uploadTask = storageReference.putFile(_image);
    await uploadTask.onComplete;
    print('File Uploaded');
    storageReference.getDownloadURL().then((fileURL) 
      setState(() 
        _avatarUrl = fileURL;
        print('Print after async function completes...');
        print(_avatarUrl);

      );
    );
  

这是输出

I/flutter ( 7332): Print before async function complete...
I/flutter ( 7332): null
I/flutter ( 7332): Print after async function completes...
I/flutter ( 7332): https://firebasestorage.googleapis.com/v0/b/sakahapa-77a09.appspot.com/o/avatars%2Fdata%2Fuser%2F0%2Fcom.sakahapa.sakaHapa%2Fcache%2Fimage_picker246664303.jpg?alt=media&token=5868d6a5-b1e3-4aa2-8e64-72dc6e9b0a0f

正如那里看到的那样,网址在SellerDatabaseService(uid:user.uid).sellerProfileSetup() 之后稍后返回 功能已运行。所以我在 avatarUrl 属性上得到一个空值。我该如何防止这种情况? 提前致谢。

【问题讨论】:

【参考方案1】:

改变这个:

    storageReference.getDownloadURL().then((fileURL) 
      setState(() 
        _avatarUrl = fileURL;
        print('Print after async function completes...');
        print(_avatarUrl);

      );
    );

进入这个:

    var fileURL = await storageReference.getDownloadURL();
      setState(() 
        _avatarUrl = fileURL;
        print('Print after async function completes...');
        print(_avatarUrl);

      );
    );

使用await 而不是then()。当前您正在输入方法uploadFile(),但由于getDownloadURL() 是异步的,因此print() 方法甚至在获取url 之前就已被执行。

【讨论】:

以上是关于Flutter firebase setData()函数在完成异步函数之前将空值分配给字段的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Firebase/Firestore 一次写入多个表

如何在firestore中获取setData的ID?

Firebase 核心依赖错误(Flutter/Firebase)

在新的 FlutterFire API 中使用 setData 和 merge: true

Flutter 和 Firebase:任务 ':firebase_auth:compileDebugJavaWithJavac' 执行失败

没有创建 Firebase 应用“[DEFAULT]” - 在 Flutter 和 Firebase 中调用 Firebase.initializeApp()