Firebase颤振分页对我不起作用 [英] Flutter pagination with firebase not working for me

查看:57
本文介绍了Firebase颤振分页对我不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试了两种可能性,但是firebase数据没有存储在产品列表中。应用页面不返回任何数据,因为产品列表中没有任何内容。下面的列表成功返回了数据。我尝试过的第二个可能性和Consolelog在下面的pastebin链接中:
https: //pastebin.com/DM47YHY6

  List< String> foollowingList = []; 
List< NetworkImage> _listOfImages =< NetworkImage> [];
List< DocumentSnapshot>产品= []; //存储获取的产品
bool isLoading = true; //跟踪是否获取
bool的产品hasMore = true; //标记是否有更多可用产品
int documentLimit = 10; //每个请求要获取的文档
DocumentSnapshot lastDocument; //标志从最后10条记录中提取的最后一个文档
ScrollController _scrollController = ScrollController(); /
void initState(){
super.initState();
getFfollowing();
getPosts();
_scrollController.addListener((){
double maxScroll = _scrollController.position.maxScrollExtent;
double currentScroll = _scrollController.position.pixels;
double delta = MediaQuery.of(context) .size.height * 0.20;
if(maxScroll-currentScroll< = delta){
getMorePosts();
}
});

}
getFfollowing()异步{
QuerySnapshot快照=等待以下引用
.document(currentUser.id)
.collection('userFollowing')
.getDocuments();
setState((){
foollowingList = snapshot.documents.map((doc)=> doc.documentID).toList();
});
}

getPosts()async {

for(int i = 0; i 查询q = Firestore .instance
.collection('posts / $ {foollowingList [i]} / userPosts')
.orderBy('ownerId')
.orderBy('timestamp',降序为true)
.limit(documentLimit);
setState((){
isLoading = true;
});
QuerySnapshot querySnapshot =等待q.getDocuments();

print( kjndskjl $ products);
lastDocument = querySnapshot.documents [querySnapshot.documents.length-1];
个产品= querySnapshot.documents;
setState((){

isLoading = false;
});
}

}
getMorePosts()async {
print('get More call');
if(hasMore == false){
return;
} if(hasMore == true){
return;
}
hasMore = true;
for(int i = 0; i< foollowingList.length; i ++){
查询q =等待Firestore.instance
.collection('posts / $ {foollowingList [i]} / userPosts ')
.orderBy('ownerId')
.orderBy('timestamp',降序为true)
.startAfterDocument(lastDocument)
.limit(documentLimit);
QuerySnapshot querySnapshot =等待q.getDocuments();
if(querySnapshot.documents.length == 0){
hasMore = false;
}
lastDocument = querySnapshot.documents [querySnapshot.documents.length-1];
products.addAll(querySnapshot.documents);
setState((){
hasMore = false;
print(products ;;
});
}


}

buildPosts(){
return
列(子项:[
Expanded(
子代:products.length == 0
?Center(
子代:Text('No Data ...'),

:ListView.builder(
控制器:_scrollController,
itemCount:products.length,
itemBuilder :(上下文,索引){
return
FutureBuilder(
future:usersRef.document (products [index] .data ['ownerId'])。get(),
构建器:(上下文,快照){
if(!snapshot.hasData){
return CircularProgress() ;
}
用户user = User.fromDocument(snapshot.data);
return Column(子级:< Widget> [
ListTile(
开头:GestureDetector(
onTap:()=> showProfile(context,profileId:user.id),
子级:CircleAvatar(
backgroundImage:CachedNetworkImageProvider(user.photoUrl),
backgroundColor:Colors.grey,
),
),
标题:GestureDetector(
onTap:()=> showProfile(context,profileId:user.id),
子项:Text(
user.displayName,
样式:TextStyle(
颜色:kText,
fontWeight:FontWeight.bold,
),
),
),
字幕: GestureDetector(
onTap:()=> showProfile(context,profileId:user.id),
child:Text(user.username,
样式:TextStyle(颜色:kIcon),),
),),
cachedNetworkImage(products [index] .data ['mediaUrl']),

Divider(color: kGrey,),
],

);
},
);

解决方案

在您的第一个代码中

  getMorePosts()async {
print('get More call');
if(hasMore == false){
return;
} if(hasMore == true){
return;
}
//其余都是无效代码,如果hasMore是true还是false,您总是返回
....
}

在您的代码段中,它似乎实际上填满了产品列表,但用户为空(在空值上调用了getter'id'),您确定 User user = User.fromDocument(snapshot.data); 正确解析了数据吗?尝试更改 showProfile(context,profileId:user?.id ?? 1)只是为了测试它(我不知道id是否应该是int,String等,但是如果是String,请用一些String'Test'更改1)


UPDATE


而不是在 initState getFfollowing

的末尾运行它

  void initState(){
super.initState();
getFfollowing();
// getPosts();这可以在getFfollowing结束之后运行,其中列表为空
_scrollController.addListener((){
double maxScroll = _scrollController.position.maxScrollExtent;
double currentScroll = _scrollController.position.pixels;
double delta = MediaQuery.of(context).size.height * 0.20;
if(maxScroll-currentScroll< = delta){
getMorePosts();
}
});
}

getFfollowing()异步{
QuerySnapshot快照=等待以下引用
.document(currentUser.id)
.collection('userFollowing')
.getDocuments();
setState((){
foollowingList = snapshot.documents.map((doc)=> doc.documentID).toList();
});
if(foollowingList.isNotEmpty)等待getPosts(); //如果确定将来已完成并且列表已满,请在此处运行
}

诀窍是initState无法运行Future,因此它将尝试按其顺序运行 getFfollowing getPosts 调用,但是将 getPosts 放入 getFfollowing 内,这是异步的,确保您仅在其他代码结束时运行。还要避免在for中使用setState,这会使它不必要地重建很多次,只需将其放在开头和结尾

  getPosts ()async {
setState(()=> isLoading = true);
for(int i = 0; i< foollowingList.length; i ++){
查询q = Firestore.instance
.collection('posts / $ {foollowingList [i]} / userPosts' )
.orderBy('ownerId')
.orderBy('timestamp',降序为true)
.limit(documentLimit);
QuerySnapshot querySnapshot =等待q.getDocuments();

print( kjndskjl $ products);
lastDocument = querySnapshot.documents [querySnapshot.documents.length-1];
个产品= querySnapshot.documents;

}
setState(()=> isLoading = false);
}


I tried two posibilities but the firebase data isnt being stored in the products list.The app page returns no data as there is nothing in procucts list. foollowing list returns data succesfully.The second possibilty that i tried and the Consolelog is in this pastebin link below: https://pastebin.com/DM47YHY6

         List<String> foollowingList = [];
List<NetworkImage> _listOfImages = <NetworkImage>[];
List<DocumentSnapshot> products = []; // stores fetched products
bool isLoading = true; // track if products fetching
bool hasMore = true; // flag for more products available or not
int documentLimit = 10; // documents to be fetched per request
DocumentSnapshot lastDocument; // flag for last document from where next 10 records to be fetched
ScrollController _scrollController = ScrollController(); /
void initState() {
  super.initState();
  getFfollowing();
  getPosts();
  _scrollController.addListener(() {
    double maxScroll = _scrollController.position.maxScrollExtent;
    double currentScroll = _scrollController.position.pixels;
    double delta = MediaQuery.of(context).size.height * 0.20;
    if (maxScroll - currentScroll <= delta) {
      getMorePosts();
    }
  });

}
getFfollowing() async {
  QuerySnapshot snapshot = await followingRef
      .document(currentUser.id)
      .collection('userFollowing')
      .getDocuments();
  setState(() {
    foollowingList = snapshot.documents.map((doc) => doc.documentID).toList();
  });
}

getPosts()async{

  for( int i=0; i< foollowingList.length; i++) {
    Query q  =  Firestore.instance
        .collection('posts/${foollowingList[i]}/userPosts')
        .orderBy('ownerId')
        .orderBy('timestamp', descending: true)
        .limit(documentLimit);
    setState(() {
      isLoading = true;
    });
    QuerySnapshot querySnapshot = await q.getDocuments();

    print("kjndskjl$products");
    lastDocument = querySnapshot.documents[querySnapshot.documents.length - 1];
    products = querySnapshot.documents;
    setState(() {

      isLoading = false;
    });
  }

}
getMorePosts()async{
  print('get more called');
  if(hasMore == false){
    return;
  } if(hasMore == true){
    return;
  }
  hasMore = true;
  for( int i=0; i< foollowingList.length; i++) {
        Query q = await Firestore.instance
          .collection('posts/${foollowingList[i]}/userPosts')
          .orderBy('ownerId')
          .orderBy('timestamp', descending: true)
          .startAfterDocument(lastDocument)
          .limit(documentLimit);
        QuerySnapshot querySnapshot = await q.getDocuments();
        if (querySnapshot.documents.length == 0) {
          hasMore = false;
        }
        lastDocument = querySnapshot.documents[querySnapshot.documents.length - 1];
        products.addAll(querySnapshot.documents);
        setState(() {
          hasMore = false;
    print(products);
        });
  }


}

buildPosts(){
  return
    Column(children: [
      Expanded(
        child: products.length == 0
            ? Center(
          child: Text('No Data...'),
        )
            : ListView.builder(
          controller: _scrollController,
          itemCount: products.length,
          itemBuilder: (context, index) {
            return
              FutureBuilder(
                future: usersRef.document(products[index].data['ownerId']).get(),
                builder: (context, snapshot) {
                  if (!snapshot.hasData) {
                    return circularProgress();
                  }
                  User user = User.fromDocument(snapshot.data);
                  return Column(children: <Widget>[
                    ListTile(
                      leading: GestureDetector(
                        onTap: () => showProfile(context, profileId: user.id),
                        child: CircleAvatar(
                          backgroundImage: CachedNetworkImageProvider(user.photoUrl),
                          backgroundColor: Colors.grey,
                        ),
                      ),
                      title: GestureDetector(
                        onTap: () => showProfile(context, profileId: user.id),
                        child: Text(
                          user.displayName,
                          style: TextStyle(
                            color: kText,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                      subtitle: GestureDetector(
                        onTap: () => showProfile(context, profileId: user.id),
                        child: Text(user.username,
                          style: TextStyle(color: kIcon),),
                      ),),
                    cachedNetworkImage(products[index].data['mediaUrl']),

                    Divider(color: kGrey,),
                  ],

                  );
                },
              );

![

解决方案

In your first code

getMorePosts()async{
  print('get more called');
  if(hasMore == false){
    return;
  } if(hasMore == true){
    return;
  }
  //The rest is dead code, you always return if hasMore is true or false
  ....
}

In your Snippet it seems it actually fills the prodcuts list but user is null (The getter 'id' was called on null), are you sure User user = User.fromDocument(snapshot.data); is parsing the data correctly? try changing showProfile(context, profileId: user?.id ?? 1) just to test it (I don't know if id should be an int, String, etc but in case of String change the 1 with some String 'Test')

UPDATE

Instead of running getPost in initState run it at the end of getFfollowing

void initState() {
  super.initState();
  getFfollowing();
  //getPosts(); this could run after getFfollowing ends, where the list is empty
  _scrollController.addListener(() {
    double maxScroll = _scrollController.position.maxScrollExtent;
    double currentScroll = _scrollController.position.pixels;
    double delta = MediaQuery.of(context).size.height * 0.20;
    if (maxScroll - currentScroll <= delta) {
      getMorePosts();
    }
  });
}

getFfollowing() async {
  QuerySnapshot snapshot = await followingRef
      .document(currentUser.id)
      .collection('userFollowing')
      .getDocuments();
  setState(() {
    foollowingList = snapshot.documents.map((doc) => doc.documentID).toList();
  });
  if(foollowingList.isNotEmpty) await getPosts(); //run it here when you're sure the future is completed and the list is full
}

The trick is that initState cannot run a Future, so it will try to run getFfollowing and getPosts in the order they're called, but putting getPosts inside getFfollowing, which is async, assure you that it will run only when the other code ends. Also try to avoid using setState inside the for, this will make it rebuild a lot of times unnecesary, just put it at the beginning and end

getPosts()async{
  setState(() => isLoading = true);
  for( int i=0; i< foollowingList.length; i++) {
    Query q  =  Firestore.instance
        .collection('posts/${foollowingList[i]}/userPosts')
        .orderBy('ownerId')
        .orderBy('timestamp', descending: true)
        .limit(documentLimit);
    QuerySnapshot querySnapshot = await q.getDocuments();

    print("kjndskjl$products");
    lastDocument = querySnapshot.documents[querySnapshot.documents.length - 1];
    products = querySnapshot.documents;
    
  }
  setState(() => isLoading = false);
}

这篇关于Firebase颤振分页对我不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆