当前位置: 首页 > 知识库问答 >
问题:

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

邹慈
2023-03-14

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

"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“应为”-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' }

所以我可以通过< code>prelSnap.key而不是< code > object . keys(prelData)[0]来获取< code>oldId。

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

  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 } } }

我期望前两个查询返回与<code>notes<code>查询相同的节点级别的结果。

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

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

亲切问候/K

共有1个答案

伍弘盛
2023-03-14

我认为您的困惑是关于查询在这里返回的内容:

dbRoot.child('contacts').orderByChild('-preliminaryId/uid').equalTo('-preliminaryId')

基于火库的查询在平面列表上运行。由于您查询了联系人,因此返回的节点将是联系人的子节点。具体来说,它返回存在属性 -初步 Id/uid 的任何联系人子节点,其值为 -初步 Id。在您的示例中,对于联系人/-ABC 的节点也是如此,这就是查询为我返回的内容。

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

"contacts": {
  "-ABC": {
     "-BCD": {
       "email": "bye@nowhere.com",
       "uid" : "-123456WWWXYz"
     },
     "-preliminaryId": {
       "email": "hello@bye.com",
       "uid": "-preliminaryId"
     }
  },
  "DEF": {
     "-HKI": {
       "uid": "another id"
     }
  }
},

在这种情况下,您的查询仍然只返回< code>-ABC节点,因为这是唯一一个< code >-prepary id/uid 具有正确值的节点。

有关这方面的工作示例,请参见:https://jsbin.com/wivukeq/edit?js安慰

 类似资料:
  • 我正在使用火库实时数据库函数 .orderByChild() 和 .equalTo() 来获取要更新的数据节点。但是,我似乎无法从查询中获得任何结果。 我的数据库结构 我的代码 代码日志 senderSnapshot null senderSnapshot金额0 我已经手动检查了有几个节点,其中“sid”设置为我正在寻找的“userId”。 为什么我的查询没有得到任何结果? 看起来我必须搜索dbR

  • 我正在尝试运行Firebase实时数据库查询,以根据从根嵌套在第4级的值过滤数据。下面是数据结构,我的查询是: 但是这个查询没有返回任何数据。我已经启用了索引,但没有任何警告。我还将我的查询改为< code >。order by child(' info status '),但没有结果。 如果我将ref设置为低于一个级别,即,那么它会成功获得结果。但是在我的场景中,我没有可以在中使用的用户ID。

  • 我正在可视化工作室上执行 Xamarin 窗体多平台应用。我使用Firebase实时数据库,并创建了一个这样的嵌套表 我需要创建一个listview,在那里我可以看到用户阅读的每本书按流派过滤。 问题是,我必须更新实时数据库的规则,并添加索引才能使用EqualTo。但是ID总是变化的,因为它是用户的UID。 我试着 但应用程序崩溃,并要求我使用整个根。有什么建议吗?

  • 在实时数据库中未创建根节点。所有依赖项均已实施,firebase已连接到该项目。这是代码。 public void onComplete(@非空任务任务){

  • 我正在使用JUnit和Mockito库来测试我的应用程序。问题是,当我在代码下面执行时,值在运行时没有返回空列表,并且测试失败。理想情况下,当get执行时,它应该返回空列表 我热切期待着支持。有没有人能帮我一下,如何通过这个测试用例???。如何通过Mockito使第8行的控件通过测试用例??? 请假设,下面两个类没有真实的代码,我们只有二进制文件作为JAR文件,我们不能修改下面的代码....我附上