我正在开发一款Android应用程序,其中年长的孩子可以捡起年幼的孩子并步行上学。随着应用程序的认证(电子邮件和密码)年轻的孩子可以选择三个地址之间得到拾取。截至目前我的实时数据库是这样的:Android - 从Firebase中检索数据
我想要检索不同的地址,谁选择了地址的用户。我想我必须使用recyclerview来获取数据,但我不确定是否可以使用我的数据库结构。
我正在开发一款Android应用程序,其中年长的孩子可以捡起年幼的孩子并步行上学。随着应用程序的认证(电子邮件和密码)年轻的孩子可以选择三个地址之间得到拾取。截至目前我的实时数据库是这样的:Android - 从Firebase中检索数据
我想要检索不同的地址,谁选择了地址的用户。我想我必须使用recyclerview来获取数据,但我不确定是否可以使用我的数据库结构。
继续从my previous answer,这一个应该符合您的要求,以创建一个所有地址及其关联用户的列表,这可能更接近你正在寻找的。
再次,您可以使用FirebaseUI database package来简化RecyclerView创建。
你需要启动非规范化的数据,所以你的数据结构也应包括地址,用户名节点:
{
"Addresses" : {
"Street 10" : {
"name" : "Street 10",
"users" : {
"VAzdMWafK6cyhmJnOI4br5xiQg93" : "John"
}
}
},
"User" : {
"VAzdMWafK6cyhmJnOI4br5xiQg93" : {
"username" : "John",
"address" : "Street 10"
}
}
}
注:您只需要用户ID添加到他们所选择的地址(和如果他们改变了选择,则删除该节点),所以不要使用"VAzdMWafK6cyhmJnOI4br5xiQg93" : false
作为用户未选择的地址,因为这可能会导致混淆。
然后你可以使用:
Query query = FirebaseDatabase.getInstance().getReference("/Addresses");
FirebaseRecyclerOptions<Address> options = new FirebaseRecyclerOptions.Builder<Address>()
.setQuery(query, Address.class)
.build();
哪里Address
是一样的东西:
public class Address {
private String name;
private Map<String, String> users;
public Address() {}
public Map<String, String> getUsers() {
return this.users;
}
// ...
}
而且create a FirebaseRecyclerAdapter
instance从options
变量。然后,在绑定适配器中的视图时,您可以访问users
映射以列出选择此地址的每个用户,而无需不必要地加载整个User
对象。
这种模式被称为denormalization,并且是使用NoSQL数据库(如Firebase实时数据库)时的建议方法。主要的缺点,这是数据复制:因此,例如,当用户改变他们所选择的地址,就需要改变:下
address
值,users
列表地址。同样,如果允许用户更改他们的用户名,则需要更新其选择的地址以及用户节点下的用户名。
有关处理此问题的详细信息,请参阅this answer which explains a number of methods(虽然示例使用JavaScript,但前提条件仍适用)。
谢谢,我会试试这个。我很抱歉从原帖 – JDoe
我刚刚完成创建FirebaseRecyclerAdapter实例的混淆。我怀疑如何访问用户映射列出我的onBindViewHolder方法中的用户。有任何想法吗? – JDoe
所以你应该可以从'onBindViewHolder()'''''''''''''参数'''''''''''''每个行''地址'模型的一个实例。然后,您可以使用'getUsers()'和[遍历此映射](https://stackoverflow.com/a/1066607)。例如:'for(String username:model.getUsers.values()){textView.append(username +“&”)}'。 – Grimthorr
使用FirebaseUI database package可以很方便地从火力地堡实时数据库到应用的UI数据绑定。特别是using FirebaseUI with indexed data适用于您当前的数据库结构。
例如,你会使用类似的东西来:
// keyQuery - the Firebase location containing the list of keys to be found in dataRef
// dataRef - the Firebase location to watch for data changes. Each key found at
// keyRef's location represents a list item.
Query keyQuery = FirebaseDatabase.getInstance().getReference("/Addresses/Street 10/users");
DatabaseReference dataRef = FirebaseDatabase.getInstance().getReference("/User");
FirebaseRecyclerOptions<User> options = new FirebaseRecyclerOptions.Builder<User>()
.setIndexedQuery(keyQuery, dataRef, User.class)
.build();
如果您的用户类是:
public class User {
private String username;
public User() {}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
// ...
}
然后,您可以使用上面创建options
变量create a FirebaseRecyclerAdapter
instance,然后调用startListening()
在上面*。
以这种方式使用FirebaseUI将自动处理将/Addresses/Street 10/users
下的密钥与/User
节点相匹配。
*版本FirebaseUI的2.x使用FirebaseIndexRecyclerAdapter
代替并自动开始听,不需要startListening()
电话。上述示例适用于3.0版,请参阅FirebaseUI 3.0 upgrade guide。
这听起来可行,但我肯定会建议看看FirebaseUI来帮助解决这个问题。它有特殊的适配器,例如'FirebaseRecyclerAdapter'。对于这个具体我看看:https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md#using-firebaseui-with-indexed-data –
感谢您的答案,我看了在你提供的链接上,但我仍然怀疑如何查询节点。我如何从Adresses节点获取用户名? – JDoe
@FrankvanPuffelen我希望你不介意我在这里跳过一个答案 - 我已经起草了之前发现你的评论! – Grimthorr