javascript - Firebase 实时数据库 - orderByChild().equalTo() 不返回预期节点
问题描述
我的 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
}
}
}
}
电子邮件“hello@bye.com”的新 ID 应为“-ultimateId123”。(我无法将电子邮件作为密钥存储在 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' }
所以我可以oldId
通过prelSnap.key
而不是Object.keys(prelData)[0]
。
然而,我真正的障碍是contacts
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" } }
我的猜测是,这可能与我的第一个查询问题有关?
当对笔记执行相同类型的查询时,一切都很好。
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 查询在平面列表上运行。由于您查询contacts
,返回的节点将是 的子节点contacts
。contact
具体来说,它返回其属性存在的任何子节点-preliminaryId/uid
,其值为-preliminaryId
。在您的示例中,节点 at 是正确的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
存在 a 且具有正确值的节点。
有关这方面的工作示例,请参阅:https ://jsbin.com/wivukeq/edit?js,console
推荐阅读
- javascript - Javascript - 如何将数组中对象的第一个元素分配为另一个数组的键
- rest - 更新资源导致位置更改后的 REST 响应
- javascript - How do I return or make null all other EventListeners if another is triggered using vanilla Javascript
- mysql - 在锁定表时重新编号mysql中的主键
- arrays - React:通过字符串映射并为每次迭代发出命令。然后计算结果
- python - 向量的一维卷积
- java - Why can a double store so much more information than a long? (JAVA)
- kubernetes - Kubernetes 声明式管理和手动命令风险
- php - 为什么 JPGraph LinePlot SetStyle 绘制一条白线而不是指定的红色虚线?
- python - HEROKU 应用程序 ModuleNotFoundError:没有名为“numpy”的模块