Javascript Firebase实时数据库-orderByChild().equalTo()未返回预期的节点

Javascript Firebase实时数据库-orderByChild().equalTo()未返回预期的节点,javascript,firebase-realtime-database,Javascript,Firebase Realtime Database,我有如下结构的Firebase实时数据库数据,我想在“联系人”和“备注”节点中将“-preliminaryId”替换为“-ultimateId123”。要执行此操作,我将删除旧节点,并用新节点替换它们 "prel":{ "-preliminaryId": { "email" : "hello@bye.com" } }, "contacts": { "-ABC"

我有如下结构的Firebase实时数据库数据,我想在“联系人”和“备注”节点中将“-preliminaryId”替换为“-ultimateId123”。要执行此操作,我将删除旧节点,并用新节点替换它们

"prel":{
  "-preliminaryId": {
    "email" : "hello@bye.com"
  }
},
"contacts": {
  "-ABC": {
     "-BCD": {
       "email": "bye@nowhere.com",
       "uid" : "-123456WWWXYz"
     },
     "-preliminaryId": {
       "email": "hello@bye.com",
       "uid": "-preliminaryId"
     }
  }
},
"notes": {
  "-noteIdone": {
    "access": {
      "members": {
        "-preliminaryId": 1
      }
    }
  },
  "-noteIdtwo": {
    "access": {
      "members": {
        "-realId1234": 1
      }
    }
  }
}
“电子邮件的新id”hello@bye.com“应为”-最终ID123”。 (我无法将电子邮件作为密钥存储在Firebase实时数据库中。)

我首先获取要替换的初始id

  const prelSnap = await dbRoot.child('prel').orderByChild('email').equalTo('hello@bye.com').once('value')
  const prelData= prelSnap.val()
  console.log('prelData', prelData)
  const oldId = Object.keys(prelData)[0]
prelData
变量将

{ -preliminaryId: { email: 'hello@bye.com' } } 
然而,我更希望它只是这样

{ email: 'hello@bye.com' }
因此,我可以通过
prelSnap.key
而不是
Object.keys(prelData)[0]
获取
olid

然而,我真正的障碍是获取
联系人

  const contactSnaps = await dbRoot.child('contacts').orderByChild(`${oldId}/uid`).equalTo(oldId).once('value')
  console.log('contactSnaps', contactSnaps.numChildren())
  contactSnaps.forEach((contact)=>{
    console.log('contactData', contact.val())
    const userId = Object.keys(contactData)[0] 
    ...
    // Replace the contact node
    myPromises.push(dbRoot.child(`contacts/${userId}/${newId}`).set(contactObj)) // Create new contact data
    myPromises.push(dbRoot.child(`contacts/${userId}/${oldId}`).remove()) // Delete old contact
    ...
  })
这将为我获取所有联系人。从
console.log('contactData',contact.val())
注销将是:

numChildren 1

contactData {
   "-BCD": {
     "email": "bye@nowhere.com",
     "uid" : "-123456WWWXYz"
   },
   -preliminaryId: {
     "email": "hello@bye.com",
     "uid": "-preliminaryId"
   }
}
硬编码示例:

const contactSnaps = await dbRoot.child('contacts').orderByChild('-preliminaryId/uid').equalTo('-preliminaryId').once('value')
console.log('contactSnapsHC', contactSnaps.numChildren())
contactSnaps.forEach((contact)=>{
  const contactData = contact.val()
  console.log('contactDataHC', contactData)
})
contactSnapsHC 1
contactDataHC { -BCD: { email: "bye@nowhere.com", uid : "-123456WWWXYz" }, -preliminaryId: { email: "hello@bye.com", uid: "-preliminaryId" } }
上述硬编码示例的输出:

const contactSnaps = await dbRoot.child('contacts').orderByChild('-preliminaryId/uid').equalTo('-preliminaryId').once('value')
console.log('contactSnapsHC', contactSnaps.numChildren())
contactSnaps.forEach((contact)=>{
  const contactData = contact.val()
  console.log('contactDataHC', contactData)
})
contactSnapsHC 1
contactDataHC { -BCD: { email: "bye@nowhere.com", uid : "-123456WWWXYz" }, -preliminaryId: { email: "hello@bye.com", uid: "-preliminaryId" } }
我猜这可能与我在第一个查询中遇到的问题有关

但是,当对notes执行相同类型的查询时,所有查询都可以正常工作

nodeSnaps = await dbRoot.child('notes').orderByChild(`access/members/${oldId}`).equalTo(1).once('value')
console.log('notes', nodeSnaps.numChildren())
nodeSnaps.forEach((node)=>{
  console.log('notesData', node.val())
  ...
}
这里的输出将是:

notes 1
notesData { "access": { "members": { "-preliminaryId": 1 } } }
我希望前两个查询在与
notes
查询相同的节点级别返回结果

如何查询数据库以返回如下所示的结果

prelData { email: 'hello@bye.com' }
contactData { email: 'hello@bye.com', uid: '-preliminaryId' }

好心的问候/K

我想您的困惑在于查询返回的内容:

dbRoot.child('contacts').orderByChild('-preliminaryId/uid').equalTo('-preliminaryId')
Firebase查询在平面列表上运行。由于查询
联系人
,因此返回的节点将是
联系人
的子节点。具体地说,它返回属性
-preliminaryId/uid
存在的
-contact
的任何子节点,该属性的值为
-preliminaryId
。在您的示例中,
contacts/-ABC
上的节点也是如此,这就是查询为我返回的结果


例如,当我在与
ABC
相同的级别上添加另一个同级节点时:

"contacts": {
  "-ABC": {
     "-BCD": {
       "email": "bye@nowhere.com",
       "uid" : "-123456WWWXYz"
     },
     "-preliminaryId": {
       "email": "hello@bye.com",
       "uid": "-preliminaryId"
     }
  },
  "DEF": {
     "-HKI": {
       "uid": "another id"
     }
  }
},
在本例中,您的查询仍然只返回
-ABC
节点,因为这是唯一一个
-preliminaryId/uid
具有正确值的节点


有关这方面的工作示例,请参阅:

firebase不允许重命名节点中的“密钥”,我建议它做什么。您已删除整个节点并重新创建它,这是一个很好的引用?您好!是的,我的计划是删除旧节点并用新节点替换它!:DIf如果我理解正确,您是说此查询
const contactsnap=await dbRoot.child('contacts').orderByChild(
${oldId}/uid
).equalTo(oldId)
没有给出预期的结果。如果这确实是问题所在,您能否使用
oldId
的硬编码值重现问题,并在代码中提供该值,以便。可以试着复制吗?嗨@FrankvanPuffelen-比你的回答!我在打印输出中添加了一个硬编码示例/KAh,好的。这是有道理的!:)我现在看到“notes”的结构不同了-少了一个级别-这就是造成所有差异的原因!:D/KI认为我开始理解你所说的“Firebase查询在平面列表上运行”的意思;D终于!再次感谢/安全的东西。您可能还想在这里查看我的答案,因为您通常使用的动态查询类型不会扩展到长列表。