Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 满足条件后,Streambuilder的颤振快照没有数据_Flutter_Dart_Google Cloud Firestore_Geofire - Fatal编程技术网

Flutter 满足条件后,Streambuilder的颤振快照没有数据

Flutter 满足条件后,Streambuilder的颤振快照没有数据,flutter,dart,google-cloud-firestore,geofire,Flutter,Dart,Google Cloud Firestore,Geofire,我有一个类Home,其中页面视图作为主体,底部导航栏。 在该类中,将加载当前用户和用户的当前位置。 当用户和位置已知时,全局变量设置为true 在底部导航栏的第一个选项卡图标上,有一个在classfeed 现在是问题。 当我第一次启动应用程序或进行热重新加载时geoQuery()返回圆形微调器。加载当前用户时,它返回文本“无数据”,而不是显示事件。用户需要将BottomNavigationBar的选项卡从feed更改为其他内容,然后再更改为feed以刷新streambuilder。在那之后,它就

我有一个类
Home
,其中页面视图作为主体,底部导航栏。 在该类中,将加载当前用户和用户的当前位置。 当用户和位置已知时,全局变量设置为true

在底部导航栏的第一个选项卡图标上,有一个在class
feed

现在是问题。 当我第一次启动应用程序或进行热重新加载时
geoQuery()
返回圆形微调器。加载当前用户时,它返回文本“无数据”,而不是显示事件。用户需要将BottomNavigationBar的选项卡从feed更改为其他内容,然后再更改为feed以刷新streambuilder。在那之后,它就如预期的那样工作了

当我在没有条件(currentLocationloaded&¤tUserloaded==true)的情况下使用streambuilder时,它会按预期工作,但有时会由于用户加载速度不够快而引发错误

我该怎么做才能使它正常工作

更新

已登录的工作流: 根页面->登录?->家

根页

enum AuthStatus {
  NOT_DETERMINED,
  NOT_LOGGED_IN,
  LOGGED_IN,
}

class RootPage extends StatefulWidget {
  RootPage({this.auth});

  final BaseAuth auth;

  @override
  State<StatefulWidget> createState() => new _RootPageState();
}

class _RootPageState extends State<RootPage> {
  AuthStatus authStatus = AuthStatus.NOT_DETERMINED;
  String _userID = "";

  @override
  void initState() {
    super.initState();
    widget.auth.getCurrentUser().then((user) {
      setState(() {
        if (user != null) {
          _userID = user?.uid;
        }
        authStatus =
            user?.uid == null ? AuthStatus.NOT_LOGGED_IN : AuthStatus.LOGGED_IN;
      });
    });
  }

  void loginCallback() {
    widget.auth.getCurrentUser().then((user) {
      setState(() {
        _userID = user.uid.toString();
      });
    });
    setState(() {
      authStatus = AuthStatus.LOGGED_IN;
    });
  }

  void logoutCallback() {
    setState(() {
      authStatus = AuthStatus.NOT_LOGGED_IN;
      _userID = "";
    });
  }

  Widget buildWaitingScreen() {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        child: CircularProgressIndicator(),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    switch (authStatus) {
      case AuthStatus.NOT_DETERMINED:
        return buildWaitingScreen();
        break;
      case AuthStatus.NOT_LOGGED_IN:
        return new StartPage(
          auth: widget.auth,
          loginCallback: loginCallback,
        );
        break;
      case AuthStatus.LOGGED_IN:
        if (_userID.length > 0 && _userID != null) {
          return new Home(
            userID: _userID,
            auth: widget.auth,
            logoutCallback: logoutCallback,
          );
        } else
          return buildWaitingScreen();
        break;
      default:
        return buildWaitingScreen();
    }
  }
}
枚举身份验证状态{
没有决心,
没有登录,
登录,
}
类RootPage扩展了StatefulWidget{
RootPage({this.auth});
最终BaseAuth-auth;
@凌驾
State createState()=>new_RootPageState();
}
类_RootPageState扩展了状态{
AuthStatus AuthStatus=未确定AuthStatus;
字符串_userID=“”;
@凌驾
void initState(){
super.initState();
widget.auth.getCurrentUser().then((用户){
设置状态(){
如果(用户!=null){
_userID=user?.uid;
}
身份=
user?.uid==null?AuthStatus.NOT_LOGGED_IN:AuthStatus.LOGGED_IN;
});
});
}
void loginCallback(){
widget.auth.getCurrentUser().then((用户){
设置状态(){
_userID=user.uid.toString();
});
});
设置状态(){
authStatus=authStatus.LOGGED\u登录;
});
}
void logoutCallback(){
设置状态(){
authStatus=authStatus.NOT\u LOGGED\u IN;
_userID=“”;
});
}
Widget BuildingWaitingScreen(){
返回脚手架(
主体:容器(
对齐:对齐.center,
子对象:CircularProgressIndicator(),
),
);
}
@凌驾
小部件构建(构建上下文){
交换机(身份验证状态){
案例身份。未确定:
返回BuildingWaitingScreen();
打破
案例身份验证状态。未登录:
返回新起始页(
auth:widget.auth,
loginCallback:loginCallback,
);
打破
案例AuthStatus.LOGGED\u登录:
如果(_userID.length>0&&u userID!=null){
返回新家(
userID:\u userID,
auth:widget.auth,
logoutCallback:logoutCallback,
);
}否则
返回BuildingWaitingScreen();
打破
违约:
返回BuildingWaitingScreen();
}
}
}

用户当前用户;
bool currentUserloaded=false;
bool currentLocationloaded=false;
类Home扩展了StatefulWidget{
最终BaseAuth-auth;
最终作废回拨注销回拨;
最终字符串用户标识;
常量Home({Key Key,this.auth,this.logoutCallback,this.userID})
:super(key:key);
@凌驾
_HomeState createState()=>\u HomeState();
}
类(HomeState扩展状态){
最终_scaffoldKey=GlobalKey();
页面控制器;
int pageIndex=0;
双经度;
双纬度;
//初始化
@凌驾
void initState(){
super.initState();
loadCurrentUser();
getCurrentLocation();
pageController=pageController();
}
//加载当前用户
loadCurrentUser()异步{
打印(“当前用户${widget.userID}”);
DocumentSnapshot doc=等待userRef.document(widget.userID.get();
currentUser=User.fromDocument(doc);
设置状态(){
currentUserloaded=true;
打印(“用户加载$currentUserloaded”);
});
}
//获取当前位置
getCurrentLocation()异步{
var currentLocationCoordinates=等待地理定位器()
.getCurrentPosition(所需精度:定位精度高);
List place=等待地理定位器()。placemarkFromCoordinates(
当前位置坐标。纬度,
当前位置坐标(经度);
纬度=当前位置坐标。纬度;
经度=当前位置坐标。经度;
设置状态(){
currentLocationloaded=true;
打印(“获取位置$currentLocationloaded”);
});
}
//处置
@凌驾
无效处置(){
pageController.dispose();
super.dispose();
}
//页面浏览
onPageChanged(int-pageIndex){
设置状态(){
this.pageIndex=pageIndex;
});
}
//点击按钮栏=>跳转到下一页
onTap(intpageindex){
if(currentUserloaded&¤tLocationloaded){
pageController.jumpToPage(页面索引);
}
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
钥匙:_scaffoldKey,
正文:页面视图(
儿童:[
提要(userID:widget.userID,纬度:纬度,经度:经度),
SearchView(),
聊天室(),
侧面图(
uid:currentUser?.uid,
auth:widget.auth,
logoutCallback:widget.logoutCallback),
],
控制器:页面控制器,
onPageChanged:onPageChanged,
物理学:NeverscrollableScroll物理学(),
),
底部导航栏:CupertinoTabBar(
currentIndex:pageIndex,
不活动颜色:颜色。白色,
背景颜色:Colors.blue,
activeColor:Colors.orange,
onTap:onTap,
项目:[
底部导航气压计(
图标:图标(Icons.home,大小:20),
标题:文本(“主页”),
),
底部导航气压计(
User currentUser;
bool currentUserloaded = false;
bool currentLocationloaded = false;

class Home extends StatefulWidget {
  final BaseAuth auth;
  final VoidCallback logoutCallback;
  final String userID;

  const Home({Key key, this.auth, this.logoutCallback, this.userID})
      : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  PageController pageController;
  int pageIndex = 0;
  double longitude;
  double latitude;

  //INIT
  @override
  void initState() {
    super.initState();
    loadCurrentUser();
    getCurrentLocation();
    pageController = PageController();
  }


  //LOAD current user
  loadCurrentUser() async {
    print("Current User ${widget.userID}");
    DocumentSnapshot doc = await userRef.document(widget.userID).get();
    currentUser = User.fromDocument(doc);
    setState(() {
      currentUserloaded = true;
      print("User loaded $currentUserloaded");
    });
  }

  //get current location
  getCurrentLocation() async {
    var currentLocationCoordinates = await Geolocator()
        .getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    List<Placemark> place = await Geolocator().placemarkFromCoordinates(
        currentLocationCoordinates.latitude,
        currentLocationCoordinates.longitude);
    latitude = currentLocationCoordinates.latitude;
    longitude = currentLocationCoordinates.longitude;
    setState(() {
      currentLocationloaded = true;
      print("Got location $currentLocationloaded");
    });
  }

  //DISPOSE
  @override
  void dispose() {
    pageController.dispose();
    super.dispose();
  }

  //Pageview
  onPageChanged(int pageIndex) {
    setState(() {
      this.pageIndex = pageIndex;
    });
  }

  //On Tap of ButtomTabbar => Jump to next Page
  onTap(int pageIndex) {
    if (currentUserloaded && currentLocationloaded) {
      pageController.jumpToPage(pageIndex);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      body: PageView(
        children: <Widget>[
          Feed(userID: widget.userID, latitude: latitude, longitude: longitude),
          SearchView(),
          ChatHome(),
          Profile(
              uid: currentUser?.uid,
              auth: widget.auth,
              logoutCallback: widget.logoutCallback),
        ],
        controller: pageController,
        onPageChanged: onPageChanged,
        physics: NeverScrollableScrollPhysics(),
      ),
      bottomNavigationBar: CupertinoTabBar(
          currentIndex: pageIndex,
          inactiveColor: Colors.white,
          backgroundColor: Colors.blue,
          activeColor: Colors.orange,
          onTap: onTap,
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home, size: 20),
              title: Text("Home"),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search, size: 20),
              title: Text("Search"),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.chat, size: 20),
              title: Text("chat"),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.profil, size: 20),
              title: Text("Profil"),
            ),
          ]),
    );
  }
}
class Feed extends StatefulWidget {
  final String userID;
  final double latitude;
  final double longitude;

  const Feed({Key key, this.userID, this.latitude, this.longitude})
      : super(key: key);

  @override
  _FeedState createState() => _FeedState();
}

class _FeedState extends State<Feed> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  List<Event> events = [];

  var radius = BehaviorSubject<double>.seeded(50.0);
  Stream<List<DocumentSnapshot>> stream;
  Geoflutterfire geo;

  @override
  void initState() {
    super.initState();
    geo = Geoflutterfire();
    GeoFirePoint center = geo.point(
        latitude: widget.latitude,
        longitude: widget
            .longitude); 
    stream = radius.switchMap((rad) {
      var collectionReference =
          eventRef.where("event", isEqualTo: "festival");
      return geo.collection(collectionRef: collectionReference).within(
          center: center, radius: rad, field: 'position', strictMode: true);
    });
  }

  //GEOQUERY

  Widget geoQuery() {
    if (currentLocationloaded && currentUserloaded) {
      return Column(
        children: <Widget>[
          StreamBuilder(
            stream: stream,
            builder: (BuildContext context,
                AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
              if (!snapshot.hasData) {
                Text("No data");
              }
              events =
                  snapshot.data.map((doc) => Event.fromDocument(doc)).toList();
              events.sort((a, b) {
                var aDate = a.timestamp;
                var bDate = b.timestamp;
                return aDate.compareTo(bDate);
              });
              if (events.isEmpty) {
                return Text("No events");
              }
              return Flexible(
                child: ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) {
                    return buildEvent(index);
                  },
                ),
              );
            },
          )
        ],
      );
    } else {
      return circularProgress();
    }
  }


  @override
  Widget build(BuildContext context) {
    SizeConfig().init(context);
    return Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          centerTitle: true,
          title: Text("Feed"),
          backgroundColor: Colors.blue,
        ),
        body: geoQuery(),
        );
  }
}
GeoFirePoint center = geo.point(
        latitude: widget.latitude,
        longitude: widget
            .longitude); 
    stream = radius.switchMap((rad) {
      var collectionReference =
          eventRef.where("event", isEqualTo: "festival");
      return geo.collection(collectionRef: collectionReference).within(
          center: center, radius: rad, field: 'position', strictMode: true);
    });