Firebase filter with pagination

2019-08-10 02:19发布

I'm doing an opensource Yelp with Firebase + Angular.

My database:

    {
      "reviews" : {
        "-L0f3Bdjk9aVFtVZYteC" : {
          "comment" : "my comment",
          "ownerID" : "Kug2pR1z3LMcZbusqfyNPCqlyHI2",
          "ownerName" : "MyName",
          "rating" : 2,
          "storeID" : "-L0e8Ua03XFG9k0zPmz-"
        },
        "-L0f7eUGqenqAPC1liYj" : {
          "comment" : "me second comment",
          "ownerID" : "Kug2pR1z3LMcZbusqfyNPCqlyHI2",
          "ownerName" : "MyName",
          "rating" : 3,
          "storeID" : "-L0e8Ua03XFG9k0zPmz-"
        },    
      },
      "stores" : {
        "-L0e8Ua03XFG9k0zPmz-" : {      
          "description" : "My good Store",      
          "name" : "GoodStore",
          "ownerID" : "39UApyo0HIXmKPrTOi8D0nWLi6n2",      
          "tags" : [ "good", "health", "cheap" ],
        }
      },
      "users" : {
        "39UApyo0HIXmKPrTOi8D0nWLi6n2" : {
          "name" : "First User"
        },
        "Kug2pR1z3LMcZbusqfyNPCqlyHI2" : {
          "name" : "MyName",
          "reviews" : {
            "-L0f3Bdjk9aVFtVZYteC" : true,
            "-L0f7eUGqenqAPC1liYj" : true
          }
        }
      }
    }

I use this code below to get all store's reviews (using AngularFire2)

    getReviews(storeID: string){
        return this.db.list('/reviews', ref => { 
            return ref.orderByChild('storeID').equalTo(storeID);
        });
    }

Now, I want to make a server-side review pagination, but I think I cannot do it with this database structure. Am I right? Tried:

    getReviews(storeID: string){
        return this.db.list('/reviews', ref => { 
            return ref.orderByChild('storeID').equalTo(storeID).limitToLast(10) //How to make pagination without retrive all data?
        });
    }

I thought that I could put all reviews inside stores, but (i) I don't want to retrieve all reviews at once when someone ask for a store and (ii) my review has a username, so I want to make it easy to change it (that why I have a denormalized table)

1条回答
狗以群分
2楼-- · 2019-08-10 02:47

For the second page you need to know two things:

  1. the store ID that you want to filter on
  2. the key of the review you want to start at

You already have the store ID, so that's easy. As the key to start at, well use the key of the last item on the previous page, and then just request one item extra. Then finally, you'll need to use start() (and possibly endAt() for this:

return this.db.list('/reviews', ref => { 
    return ref.orderByChild('storeID')
              .startAt(storeID, lastKeyOnPreviousPage)
              .limitToLast(11)
});
查看更多
登录 后发表回答