Firebase延迟加载

时间:2017-05-14 12:15:13

标签: javascript firebase firebase-realtime-database firebase-security

我试图延迟加载firebase项目,以便稍后在用户到达div容器的末尾时加载更多的项目。当我删除.endAt().startAt()时我收到了15件物品,虽然他们没有增加,但是他们仍然坚持这15件物品。

当我保持.endAt().startAt()时,我正在接收火力警告 Using an unspecified index. Consider adding ".indexOn": "title" at /items即使设置了.indexOn。我对这个警告感到困惑。提前感谢您的帮助。

Firebase结构

{
  "items" : {
    "-Kk6aHXIyR15XiYh65Ht" : {
      "author" : "joe", 
      "title" : "Product 1"
    },
    "-Kk6aMQlh6_E3CJt_Pnq" : {
      "author" : "joe",
      "title" : "Product 2"
    }
  },
  "users" : {
    "RG9JSm8cUndpjMfZiN6c657DMIt2" : {
      "items" : {
        "-Kk6aHZs5xyOWM2fHiPV" : "-Kk6aHXIyR15XiYh65Ht",
        "-Kk6aMTJiLSF-RB3CZ-2" : "-Kk6aMQkw5bLQst81ft7"
      },
      "uid" : "RG9JSm8cUndpjMfZiN6c657DMIt2",
      "username" : "joe"
    }
  }
}

安全规则

{
  "rules": {
    ".read": true,  
    ".write": "auth != null",  
    "users":{
      "$uid": {
        ".write": "$uid === auth.uid"
        "items":{
          ".indexOn": "title",
          "$itemId": {
            "title": {".validate": "...}
            "type": {".validate": "...}
            }
          }
        }
      }
    }
  }
}

延迟加载的代码结构

let _start = 0,
    _end = 14,
    _n = 15;

function lazyLoadItems(){
  firebase.database().ref('items')
        .orderByChild('title')
        .startAt(_start)
        .endAt(_end)
        .limitToFirst(_n)
        .on("child_added", snapshot=> console.log(snapshot.val()));
  _start += _n;
  _end += _n;
}

2 个答案:

答案 0 :(得分:4)

您误解了Firebase查询的工作原理。如果您使用硬编码值,最容易看到:

firebase.database().ref('items')
    .orderByChild('title')
    .startAt(0)
    .endAt(14)
    .limitToFirst(15)

没有title=0title=14的项目,因此查询不匹配任何内容。

Firebase数据库查询与您订购的媒体资源的价值相匹配。因此,当您按title订购时,您在startAtendAt中指定的值必须是标题。 E.g。

ref.child('items')
   .orderByChild('title')
   .startAt("Product 1")
   .endAt("Product 1")
   .limitToFirst(15)
   .on("child_added", function(snapshot) { console.log(snapshot.val()); });

请参阅此工作示例:http://jsbin.com/hamezu/edit?js,console

要实施分页,您必须记住上一页的最后一项并将其传递给下一个电话:startAt(titleOfLastItemOnPreviousPage, keyOfLastItemOnPreviousPage)

答案 1 :(得分:0)

startAfter 是最后一个元素

每次必须发送最后一个元素时:

const lastAlert = querySnapshot.docs[querySnapshot.docs.length - 1]

这里有一个例子:

export const fetchAlerts = (createdForId, startAfter) => {
  return new Promise((resolve, reject) => {
    firebase
    let query = firebase
      .firestore()
      .collection('alerts')
      .where('generated_for.uid', '==', createdForId)
      .where('read', '==', false)
      .orderBy('created_at', 'desc')
      .limit(25)
    if (startAfter) {
      query = query.startAfter(startAfter)
    }

    query
      .get()
      .then(querySnapshot => {
        const lastAlert = querySnapshot.docs[querySnapshot.docs.length - 1]
        const alerts = querySnapshot.docs.map(doc => ({
          ...doc.data(),
          uid: doc.id,
        }))
        resolve(alerts)
        resolve({ alerts, lastAlert })
      })
      .catch(error => {
        console.log(error.message)