Подождите, пока будущая функция завершит свое выполнение - PullRequest
0 голосов
/ 21 июня 2020

Я новичок в флаттере, и в моем приведенном ниже коде функция чтения данных вызывается в строке 18 (она выполняет операции с базой данных Firebase). Я хочу, чтобы функция readData () должна завершить свое выполнение перед тем, как перейти в оператор печати (строка 19) и дальнейшее выполнение.

import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/cupertino.dart';
import 'package:udharibook/Screens/SignInPage.dart';
import 'package:udharibook/Screens/UserProfile.dart';
import 'package:udharibook/Screens/dashboard.dart';

class AuthService  {
  bool flag = false;
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final DBRef = FirebaseDatabase.instance.reference().child('Users');

    handleAuth(){
    return StreamBuilder(
      stream: FirebaseAuth.instance.onAuthStateChanged,
      builder: (BuildContext, snapshot) {
        if(snapshot.hasData) {
         readData();
          print(flag);
          if(flag ==true)
            return DashboardPage();
          else
            return UserProfile();
        }
        else {
          return SignIn();
        }
      },
    );
  }

  Future<void> readData() async {
    final FirebaseUser user = await _auth.currentUser();
    final userid = user.uid;
    DBRef.child(userid).once().then((DataSnapshot data){
      print(userid);
      if(data.value!=null)
        {
          flag =  true;
          print(data.key);
          print(data.value);
        }
      else{
        print('User not found');
        flag = false;
      }
    });
  }

  signOut(){
    FirebaseAuth.instance.signOut();
  }

  signIn(AuthCredential authCreds){
    FirebaseAuth.instance.signInWithCredential(authCreds);
  }

  signInWithOTP(smsCode,verId){
    AuthCredential authCreds = PhoneAuthProvider.getCredential(
        verificationId: verId,
        smsCode: smsCode
    );
    signIn(authCreds);
  }
}

Ответы [ 2 ]

0 голосов
/ 21 июня 2020

Поскольку readData () является An AsyncFunction ,

Добавление ключевого слова await перед readData () приведет к тому, что readData () будет fini sh, и после этого он напечатает Однако вы не можете этого сделать, так как StreamBuilder ожидает возврата типа Widget.

Итак, что вы можете сделать, это. возможно, измените свои readData, чтобы вернуть Future boolean readData ();

 Future<bool> readData() async {
    final FirebaseUser user = await _auth.currentUser();
    final userid = user.uid;
    DBRef.child(userid).once().then((DataSnapshot data){
      print(userid);
      if(data.value!=null)
        {
          print(data.key);
          print(data.value);
          return true;
         
        }
      else{
        print('User not found');
        return false;
      }
    });
  }

, и вы назовете его:

readData().then((value)
{
 if (value ==true)
return Widget
else
return Widget;

}
);

Надеюсь, что это поможет.

0 голосов
/ 21 июня 2020

Если вы хотите, чтобы будущее завершалось внутри метода сборки / компоновщика, то использование FutureBuilder - хороший способ go. Таким образом, вы можете настроить виджет-заполнитель, пока будущее завершается, а затем, когда он будет готов, вывести желаемые результаты. В приведенном ниже примере я использовал круговой индикатор выполнения в качестве заполнителя, но вы можете использовать любой виджет:

return StreamBuilder(
  stream: FirebaseAuth.instance.onAuthStateChanged,
  builder: (BuildContext, snapshot) {
    if(snapshot.hasData) {
      return FutureBuilder(
        future: readData(),
        builder: (context, futureSnapshot) {
          if (!futureSnapshot.hasData) return CircularProgressIndicator();

          print(flag);
          if(flag ==true)
            return DashboardPage();
          else
            return UserProfile();
        }
      );
    }
    else {
      return SignIn();
    }
  },
);
...