Firestore 查询 endBefore 和 endAt 未按预期工作

问题描述 投票:0回答:2

我使用的是 Node 10、firebase 8.0、firebase-admin 9.3.0。我已经包含了我的测试代码和客户端 js 版本的副本。

数据

Document ID | name | is_visible
----------- | ---- | ----------
     1      |   a  | true
     2      |   b  | true
     3      |   c  | true
     4      |   d  | true
     5      |   e  | true
     6      |   f  | true
     7      |   g  | true
     8      |   h  | true
     9      |   i  | true

代码

var admin = require("firebase-admin");

const firebaseConfig = {xxx}

admin.initializeApp({
    credential: admin.credential.cert(firebaseConfig)
  });

const getDocs = async () =>{

  try {

    const cursor = await admin.firestore().collection('ordering').doc('5').get();

    const beforeDocs = await admin.firestore().collection('ordering')
    .orderBy("name", "desc")
    .endAt(cursor)
    .limit(2)
    .get()


      beforeDocs.forEach((doc)=> {
        console.log("Doc ID - ",doc.id, ", Name -", doc.get('name'));
      })

    
    const afterDocs = await admin.firestore().collection('ordering')
      .orderBy("name", "desc")
      .startAt(cursor)
      .limit(2)
      .get()


    afterDocs.forEach((doc)=> {
      console.log("Doc ID - ",doc.id, ", Name -", doc.get('name'));
    })

  }
  catch (error) {
    console.error(error);
  }
}

getDocs();

使用

node getDocs.js

运行

期待结果

Doc ID -  6 , Name - f
Doc ID -  5 , Name - e
Doc ID -  5 , Name - e
Doc ID -  4 , Name - d

实际结果

Doc ID -  9 , Name - i
Doc ID -  8 , Name - h
Doc ID -  5 , Name - e
Doc ID -  4 , Name - d

我对 endAt 的临时解决办法是使用 startAt 将顺序反转为“asc”,然后在 QuerySnapshot 中反转 forEach 之前的文档数组。

我创建了这个JS来显示我的问题,这是我的测试集合的运行,它非常粗糙,请友善,输出到控制台。

我显然做错了什么,但只是不确定是什么。

<script src="https://www.gstatic.com/firebasejs/8.0.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.0.0/firebase-firestore.js"></script>

<body>
  <div id="output">Check the console!</div>
</body>
<script>

  var firebaseConfig = {
    apiKey: "AIzaSyAxLEo7LfABdATToJTMQGae3Vgum_CAlQg",
    authDomain: "bmtestbase.firebaseapp.com",
    databaseURL: "https://bmtestbase.firebaseio.com",
    projectId: "bmtestbase",
    storageBucket: "bmtestbase.appspot.com",
    messagingSenderId: "326028950684",
    appId: "1:326028950684:web:74b55887466c63b4a9c159"
  };

  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
  
const db = firebase.firestore()
   
// Setting the Focus point using a Snapshot 
db.collection('ordering').get()
  .then (docs => {
    docs.forEach(doc => {
          console.log("MYCODE_allDocs: DocID ", doc.id, ", Name ", doc.get('name'))
    })
  })

db.collection('ordering').doc('5').get()
  .then( focusSnapshot => {

    db.collection("ordering")
      .orderBy("name", "asc")
      .endAt(focusSnapshot)
      .limit(2)
      .get()
    .then(docs => {
  
       console.log("MYCODE_endAt_expected:","DocID 4, Name d")
       console.log("MYCODE_endAt_expected:","DocID 5, Name e")      

      docs.forEach(doc => {  
        console.log("MYCODE_endAt:","DocID ", doc.id, ", Name ", doc.get('name'))
      }); 
    })


    db.collection("ordering")
      .orderBy("name", "asc")
      .startAt(focusSnapshot)
      .limit(2)
      .get()
    .then(docs => {

       console.log("MYCODE_startAt_expected:","DocID 5, Name e")
       console.log("MYCODE_startAt_expected:","DocID 6, Name f")      

      docs.forEach(doc => {  
        console.log("MYCODE_startAt:","DocID ", doc.id, ", Name ", doc.get('name'))
      }); 
    })
  
})

</script>

node.js google-cloud-firestore firebase-admin
2个回答
12
投票

根据 firebase 支持,您需要将 limitToLastendBeforeendAt

一起使用

像这样重写你的示例应该可行:

<script src="https://www.gstatic.com/firebasejs/8.0.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.0.0/firebase-firestore.js"></script>

<body>
  <div id="output">Check the console!</div>
</body>
<script>

  var firebaseConfig = {
    apiKey: "AIzaSyAxLEo7LfABdATToJTMQGae3Vgum_CAlQg",
    authDomain: "bmtestbase.firebaseapp.com",
    databaseURL: "https://bmtestbase.firebaseio.com",
    projectId: "bmtestbase",
    storageBucket: "bmtestbase.appspot.com",
    messagingSenderId: "326028950684",
    appId: "1:326028950684:web:74b55887466c63b4a9c159"
  };

  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
  
const db = firebase.firestore()
   
// Setting the Focus point using a Snapshot 
db.collection('ordering').get()
  .then (docs => {
    docs.forEach(doc => {
          console.log("MYCODE_allDocs: DocID ", doc.id, ", Name ", doc.get('name'))
    })
  })

db.collection('ordering').doc('5').get()
  .then( focusSnapshot => {

    db.collection("ordering")
      .orderBy("name", "asc")
      .endAt(focusSnapshot)
      .limitToLast(2)
      .get()
    .then(docs => {
  
       console.log("MYCODE_endAt_expected:","DocID 4, Name d")
       console.log("MYCODE_endAt_expected:","DocID 5, Name e")      

      docs.forEach(doc => {  
        console.log("MYCODE_endAt:","DocID ", doc.id, ", Name ", doc.get('name'))
      }); 
    })


    db.collection("ordering")
      .orderBy("name", "asc")
      .startAt(focusSnapshot)
      .limit(2)
      .get()
    .then(docs => {

       console.log("MYCODE_startAt_expected:","DocID 5, Name e")
       console.log("MYCODE_startAt_expected:","DocID 6, Name f")      

      docs.forEach(doc => {  
        console.log("MYCODE_startAt:","DocID ", doc.id, ", Name ", doc.get('name'))
      }); 
    })
  
})

</script>


0
投票

同意! 您应该将 .limit() 替换为 .limitToLast() 。 之后 .EndBefore() 和 .EndAt() 方法将起作用。

© www.soinside.com 2019 - 2024. All rights reserved.