Функция Flutter firebase setData () присваивает нулевое значение полю перед завершением функции asyn c - PullRequest
2 голосов
/ 14 июля 2020

Я пытаюсь загрузить аватар для пользователя в хранилище firestore и вернуть URL-адрес изображения, чтобы сохранить его в отношении свойства avatarUrl пользователя в экземпляре пользователя. Я могу успешно загрузить изображение в firestore. проблема связана с получением URL-адреса. Функция asyn c задерживается, и, следовательно, предыдущая функция создания экземпляра пользователя переходит к нулевому значению для свойства 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

Как видно, URL-адрес возвращается позже после запуска функции SellerDatabaseService(uid:user.uid).sellerProfileSetup(). Итак, я получаю нулевое значение свойства avatarUrl. Как мне предотвратить это? Заранее спасибо.

1 Ответ

1 голос
/ 14 июля 2020

Измените это:

    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.

...