Firebase实时数据库如何在没有密钥的情况下获取子记录
Posted
技术标签:
【中文标题】Firebase实时数据库如何在没有密钥的情况下获取子记录【英文标题】:Firebase realtime database how to get a child record without the key 【发布时间】:2021-11-26 05:25:34 【问题描述】:我有一个带有“用户”节点的 Firebase 数据库,该节点有一些子节点,我想检索特定用户的“类型”字段,但我不知道该用户的密钥是什么。我有以下数据结构:
users
-MlHrU3_UgMzrU3IpfOW
email:
"mail@gmail.com"
tipo:
"Aluno"
我尝试这样做,但它总是返回 null
final String[] tipoUserBD = new String[1];
database = FirebaseDatabase.getInstance().getReference("users");
database.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
list.clear();
for(DataSnapshot dataSnapshot : snapshot.getChildren())
if(dataSnapshot.child("email").getValue(String.class).equals(user.getEmail()))
tipoUser[0] = dataSnapshot.child("tipo").getValue().toString();
@Override
public void onCancelled(@NonNull DatabaseError error)
);
【问题讨论】:
"我想检索特定用户的“类型”字段" 您对特定用户了解多少?如果你对他们一无所知,你能做的最好的就是阅读所有用户。 【参考方案1】:如果您知道用户的密钥(我知道您不知道,但我们假设您在其他情况下知道),您可以阅读他们的个人资料并记录他们的类型:
database = FirebaseDatabase.getInstance().getReference("users");
database.child("-MlHrU3_UgMzrU3IpfOW").addValueEventListener(new ValueEventListener()
// ? use the key here
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
Log.d("Tipo", dataSnapshot.child("tipo").getValue(String.class)); // ? Specify type here
@Override
public void onCancelled(@NonNull DatabaseError error)
throw error.toException(); // ? never ignore errors
);
如果您知道一些标识用户的属性,但不知道键,您可以使用查询来查找匹配的节点:
database = FirebaseDatabase.getInstance().getReference("users");
database.orderByChild("email").equalTo("mail@gmail.com").addValueEventListener(new ValueEventListener()
// ? use the property name and value here
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
for(DataSnapshot dataSnapshot : snapshot.getChildren())
Log.d("Tipo", dataSnapshot.child("tipo").getValue(String.class)); // ? Specify type here
@Override
public void onCancelled(@NonNull DatabaseError error)
throw error.toException(); // ? never ignore errors
);
如果您对用户一无所知,最好的办法就是遍历所有用户:
database = FirebaseDatabase.getInstance().getReference("users");
database.addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(@NonNull DataSnapshot snapshot)
for(DataSnapshot dataSnapshot : snapshot.getChildren())
Log.d("Tipo", dataSnapshot.child("tipo").getValue(String.class));
@Override
public void onCancelled(@NonNull DatabaseError error)
throw error.toException(); // ? never ignore errors
);
您尝试使用 tipoUser[0]
的技巧是一种反模式,因为这通常意味着您忽略了异步加载的数据。
作为一般(和硬性)规则:任何需要数据库数据的代码都需要内部 onDataChange
或从那里调用。
有关这方面的更多信息和示例,请参阅:
getContactsFromFirebase() method return an empty list
Setting Singleton property value in Firebase Listener
【讨论】:
它可以在日志中打印用户的类型,但是当我将此值分配给字符串类型的变量时,应用程序会给出一个错误,好像该变量为空:( 在没有看到代码和错误的情况下有点难以确定,但我的猜测是您仍在尝试使用onDataChange
/onDataChange
之外的数据库中的数据已经跑了。我的答案的最后一部分解释了为什么这不起作用,并且链接显示了更多关于此的内容 - 以及如何在 onDataChange
中实现代码或使用回调。以上是关于Firebase实时数据库如何在没有密钥的情况下获取子记录的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 ASP.NET MVC 应用程序在 firebase 实时数据库中设置数据
关于使用android studio在firebase实时数据库中的uid下创建随机密钥
我可以在没有实时数据库的情况下访问 Firebase 存储吗