我正在開發一款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