Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.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
Javascript 如何重新订购Firestore';修改';使用DocumentChange.newIndex进行更改?_Javascript_Firebase_Google Cloud Firestore - Fatal编程技术网

Javascript 如何重新订购Firestore';修改';使用DocumentChange.newIndex进行更改?

Javascript 如何重新订购Firestore';修改';使用DocumentChange.newIndex进行更改?,javascript,firebase,google-cloud-firestore,Javascript,Firebase,Google Cloud Firestore,我正在使用Firestore的web API对格式化为字符串(“2017-12-30”)的日期属性执行简单的查询。我使用onSnapshot()方法作为侦听器订阅文档更改。结果列表的初始填充按预期工作-顺序正确 当我对数据进行更改时,将使用“modified”更改类型调用回调。如果任何更改都会影响date属性,那么我就无法在结果列表中对该项重新排序,这与旧的实时数据库不同。也就是说,直到我看到DocumentChange的newIndex和oldIndex属性。它们没有针对Web API()进行

我正在使用Firestore的web API对格式化为字符串(“2017-12-30”)的日期属性执行简单的查询。我使用onSnapshot()方法作为侦听器订阅文档更改。结果列表的初始填充按预期工作-顺序正确

当我对数据进行更改时,将使用“modified”更改类型调用回调。如果任何更改都会影响date属性,那么我就无法在结果列表中对该项重新排序,这与旧的实时数据库不同。也就是说,直到我看到DocumentChange的newIndex和oldIndex属性。它们没有针对Web API()进行记录,但作为Node.js API()的一部分进行了记录

因此,我的问题似乎得到了解决——除了在实践中,newIndex和oldinex中的值在很大程度上是随机的,如果我刷新查询,它们与实际顺序没有关系。我无法找出任何模式来解释我得到的索引值

是否有人成功使用了DocumentChange.newIndex和DocumentChange.oldIndex?如果没有,您将如何根据更改对订阅服务器中的结果进行重新排序

const query = firestore.collection(`users/${uid}/things`).
  orderBy('sortDate', 'desc').limit(1000)
query.onSnapshot(snapshot => {
  snapshot.docChanges.forEach(change => {
    if (change.type === "added") {
      dispatch(addThing({
        id: change.doc.id, 
        ...change.doc.data()
      }, change.newIndex)
    }
    if (change.type === "modified") {
      dispatch(changeThing({
        id: change.doc.id, 
        ...change.doc.data()
      }, change.oldIndex, change.newIndex))
    }
    if (change.type === "removed") {
      dispatch(removeThing(change.doc.id, change.oldIndex))
    }
  })
})

我对DocumentChange索引的最初问题是由于代码中其他地方的几个bug造成的。由于我在Node.js Firestore文档之外没有发现任何此类示例,因此下面是我用来验证其正确行为的测试代码(ES6)。它假定firebase已初始化

cleanTestData = (firestore, path) => {
  console.log("Cleaning-up old test data")
  var query = firestore.collection(path)
  return query.get().then(snapshot => {

    const deletePromises = []
    if (snapshot.size > 0) {
      snapshot.docs.forEach(function(doc) {
        deletePromises.push(doc.ref.delete().then(() => {
          console.log("Deleted ", doc.id)
        }))
      });
    }
    return Promise.all(deletePromises)
  }).then(() => {
    console.log("Old test data cleaned-up")
  })
}

createTestData = (firestore, path) => {
  console.log("Creating test data")
  const batch = firestore.batch()    
  const data = { 
    a: '2017-09-02',
    b: '2017-12-25',
    c: '2017-10-06',
    d: '2017-08-02',
    e: '2017-09-20',
    f: '2017-11-17' 
  }
  for (const id in data) {
    batch.set(firestore.collection(path).doc(id), { date: data[id] })
  }

  return batch.commit().then(() => {
    console.log("Test data created");
  }).catch(error => {
    console.error("Failed to create test data: ", error);
  })
}

subscribe = (firestore, path) => {
  const datesArray = []

  return firestore.collection(path).orderBy('date', 'asc').onSnapshot(snapshot => {  
    snapshot.docChanges.forEach(change => {
      console.log(change.type, "id:", change.doc.id, 
        "; date:", change.doc.data().date, 
        "; oldIndex:", change.oldIndex, "; newIndex:", change.newIndex,
        "; metadata: ", change.doc.metadata)
      if (change.oldIndex !== -1) {
        datesArray.splice(change.oldIndex, 1);
      }
      if (change.newIndex !== -1) {
        datesArray.splice(change.newIndex, 0, change.doc.data().date);
      }
      console.log("    -->", JSON.stringify(datesArray))
    })
  })
}

update = (firestore, path) => {
  console.log("Updating test data")
  return firestore.collection(path).doc('d').set({date: '2018-01-02'}).then(() => {
    console.log("Test doc 'd' updated from '2017-08-02' to '2018-01-02'")
  })
}

query = (firestore, path) => {
  var query = firestore.collection(path).orderBy('date', 'asc')
  return query.get().then(snapshot => {

    const dates = []
    if (snapshot.size > 0) {
      snapshot.docs.forEach(function(doc) {
        dates.push(doc.data().date)
      });
    }

    console.log("Fresh query of data: \n    -->", JSON.stringify(dates))
  })
}

handleStartTest = e => {
  console.log("Starting test")

  const firestore = firebase.firestore()
  const path = `things`
  let unsubscribeFn = null

  unsubscribeFn = this.subscribe(firestore, path)
  this.cleanTestData(firestore, path).then(() => {
    return this.createTestData(firestore, path)
  }).then(() => {
    return this.update(firestore, path)
  }).then(() => {
    return this.query(firestore, path)
  }).then(() => {
    unsubscribeFn()
    console.log("Test complete")
  }).catch((error) => {
    console.error("Test failed: ", error)
  })
}

我对DocumentChange索引的最初问题是由于代码中其他地方的几个bug造成的。由于我在Node.js Firestore文档之外没有发现任何此类示例,因此下面是我用来验证其正确行为的测试代码(ES6)。它假定firebase已初始化

cleanTestData = (firestore, path) => {
  console.log("Cleaning-up old test data")
  var query = firestore.collection(path)
  return query.get().then(snapshot => {

    const deletePromises = []
    if (snapshot.size > 0) {
      snapshot.docs.forEach(function(doc) {
        deletePromises.push(doc.ref.delete().then(() => {
          console.log("Deleted ", doc.id)
        }))
      });
    }
    return Promise.all(deletePromises)
  }).then(() => {
    console.log("Old test data cleaned-up")
  })
}

createTestData = (firestore, path) => {
  console.log("Creating test data")
  const batch = firestore.batch()    
  const data = { 
    a: '2017-09-02',
    b: '2017-12-25',
    c: '2017-10-06',
    d: '2017-08-02',
    e: '2017-09-20',
    f: '2017-11-17' 
  }
  for (const id in data) {
    batch.set(firestore.collection(path).doc(id), { date: data[id] })
  }

  return batch.commit().then(() => {
    console.log("Test data created");
  }).catch(error => {
    console.error("Failed to create test data: ", error);
  })
}

subscribe = (firestore, path) => {
  const datesArray = []

  return firestore.collection(path).orderBy('date', 'asc').onSnapshot(snapshot => {  
    snapshot.docChanges.forEach(change => {
      console.log(change.type, "id:", change.doc.id, 
        "; date:", change.doc.data().date, 
        "; oldIndex:", change.oldIndex, "; newIndex:", change.newIndex,
        "; metadata: ", change.doc.metadata)
      if (change.oldIndex !== -1) {
        datesArray.splice(change.oldIndex, 1);
      }
      if (change.newIndex !== -1) {
        datesArray.splice(change.newIndex, 0, change.doc.data().date);
      }
      console.log("    -->", JSON.stringify(datesArray))
    })
  })
}

update = (firestore, path) => {
  console.log("Updating test data")
  return firestore.collection(path).doc('d').set({date: '2018-01-02'}).then(() => {
    console.log("Test doc 'd' updated from '2017-08-02' to '2018-01-02'")
  })
}

query = (firestore, path) => {
  var query = firestore.collection(path).orderBy('date', 'asc')
  return query.get().then(snapshot => {

    const dates = []
    if (snapshot.size > 0) {
      snapshot.docs.forEach(function(doc) {
        dates.push(doc.data().date)
      });
    }

    console.log("Fresh query of data: \n    -->", JSON.stringify(dates))
  })
}

handleStartTest = e => {
  console.log("Starting test")

  const firestore = firebase.firestore()
  const path = `things`
  let unsubscribeFn = null

  unsubscribeFn = this.subscribe(firestore, path)
  this.cleanTestData(firestore, path).then(() => {
    return this.createTestData(firestore, path)
  }).then(() => {
    return this.update(firestore, path)
  }).then(() => {
    return this.query(firestore, path)
  }).then(() => {
    unsubscribeFn()
    console.log("Test complete")
  }).catch((error) => {
    console.error("Test failed: ", error)
  })
}

我使用索引来保持本地数组与服务器上的数据同步,并且没有任何问题。但很难理解“随机”在这里的含义。您能否显示一些示例数据、您对该数据所做的更改以及您因该更改而获得的事件(包括索引);我花了一些时间编写了一个测试用例,它工作得非常好。然后,我确定在我的原始代码(a)中,我的add逻辑中有一个bug,它颠倒了元素添加的顺序;这掩盖了一个错误(b),即我的排序顺序方向错误。实际上,这意味着引入的索引与查询的排序顺序相反。这段混乱的代码是从实时数据库迁移到Firestore的一半。无论如何,谢谢你的帮助。我将把测试用例作为答案发布,以防它对其他人有帮助。很高兴听到你发现了这个问题。感谢您将其作为解决方案分享!我使用索引来保持本地数组与服务器上的数据同步,并且没有任何问题。但很难理解“随机”在这里的含义。您能否显示一些示例数据、您对该数据所做的更改以及您因该更改而获得的事件(包括索引);我花了一些时间编写了一个测试用例,它工作得非常好。然后,我确定在我的原始代码(a)中,我的add逻辑中有一个bug,它颠倒了元素添加的顺序;这掩盖了一个错误(b),即我的排序顺序方向错误。实际上,这意味着引入的索引与查询的排序顺序相反。这段混乱的代码是从实时数据库迁移到Firestore的一半。无论如何,谢谢你的帮助。我将把测试用例作为答案发布,以防它对其他人有帮助。很高兴听到你发现了这个问题。感谢您将其作为解决方案分享!