Reputation: 3407
I have Firebase Realtime Database data structured as below where I want to replace "-preliminaryId" with "-ultimateId123" in the "contacts" and "notes" nodes. To perform this I will delete the old nodes and replace them with new nodes.
"prel":{
"-preliminaryId": {
"email" : "[email protected]"
}
},
"contacts": {
"-ABC": {
"-BCD": {
"email": "[email protected]",
"uid" : "-123456WWWXYz"
},
"-preliminaryId": {
"email": "[email protected]",
"uid": "-preliminaryId"
}
}
},
"notes": {
"-noteIdone": {
"access": {
"members": {
"-preliminaryId": 1
}
}
},
"-noteIdtwo": {
"access": {
"members": {
"-realId1234": 1
}
}
}
}
The new id for email "[email protected]" should be "-ultimateId123". (I cannot store email as keys in Firebase Realtime Database.)
I begin by fetching the preliminary id to replace.
const prelSnap = await dbRoot.child('prel').orderByChild('email').equalTo('[email protected]').once('value')
const prelData= prelSnap.val()
console.log('prelData', prelData)
const oldId = Object.keys(prelData)[0]
The prelData
variable will be
{ -preliminaryId: { email: '[email protected]' } }
However, I would prefer it to just be
{ email: '[email protected]' }
so I can get oldId
by prelSnap.key
instead of Object.keys(prelData)[0]
.
However, my real hurdle is fetching 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
...
})
This will get me ALL contacts. The logout from console.log('contactData', contact.val())
will be:
numChildren 1
contactData {
"-BCD": {
"email": "[email protected]",
"uid" : "-123456WWWXYz"
},
-preliminaryId: {
"email": "[email protected]",
"uid": "-preliminaryId"
}
}
Hardcoded example:
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)
})
Output from above hardcoded example:
contactSnapsHC 1
contactDataHC { -BCD: { email: "[email protected]", uid : "-123456WWWXYz" }, -preliminaryId: { email: "[email protected]", uid: "-preliminaryId" } }
My guess is that this might be somewhat related to my issue with the first query?
When performing the same type of query on notes, all works well though.
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())
...
}
The output here will be:
notes 1
notesData { "access": { "members": { "-preliminaryId": 1 } } }
I expected the first two queries to return result at the same node level as the notes
query.
How can I query the database to return the result shown below?
prelData { email: '[email protected]' }
contactData { email: '[email protected]', uid: '-preliminaryId' }
Kind regards /K
Upvotes: 2
Views: 362
Reputation: 598740
I think your confusion is about what the query returns here:
dbRoot.child('contacts').orderByChild('-preliminaryId/uid').equalTo('-preliminaryId')
Firebase queries operate on a flat list. Since you query contacts
, the nodes returned will be child nodes of contacts
. Specifically, it returns any child node of contact
for which a property -preliminaryId/uid
exists, which has a value of -preliminaryId
. In your example that is true for the node at contacts/-ABC
, which is what the query returns for me.
For example, when I add another sibling node on the same level as ABC
:
"contacts": {
"-ABC": {
"-BCD": {
"email": "[email protected]",
"uid" : "-123456WWWXYz"
},
"-preliminaryId": {
"email": "[email protected]",
"uid": "-preliminaryId"
}
},
"DEF": {
"-HKI": {
"uid": "another id"
}
}
},
Your query in this case still only returns the -ABC
node, since that's the only one where a -preliminaryId/uid
exists with the correct value.
For a working example of this, see: https://jsbin.com/wivukeq/edit?js,console
Upvotes: 1