2017-10-13 140 views
1

我正在開發一款Android應用程序,其中年長的孩子可以撿起年幼的孩子並步行上學。隨着應用程序的認證(電子郵件和密碼)年輕的孩子可以選擇三個地址之間得到拾取。截至目前我的實時數據庫是這樣的:Android - 從Firebase中檢索數據

enter image description here

我想要檢索不同的地址,誰選擇了地址的用戶。我想我必須使用recyclerview來獲取數據,但我不確定是否可以使用我的數據庫結構。

enter image description here

+0

這聽起來可行,但我肯定會建議看看FirebaseUI來幫助解決這個問題。它有特殊的適配器,例如'FirebaseRecyclerAdapter'。對於這個具體我看看:https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md#using-firebaseui-with-indexed-data –

+0

感謝您的答案,我看了在你提供的鏈接上,但我仍然懷疑如何查詢節點。我如何從Adresses節點獲取用戶名? – JDoe

+0

@FrankvanPuffelen我希望你不介意我在這裏跳過一個答案 - 我已經起草了之前發現你的評論! – Grimthorr

回答

1

繼續從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 instanceoptions變量。然後,在綁定適配器中的視圖時,您可以訪問users映射以列出選擇此地址的每個用戶,而無需不必要地加載整個User對象。

這種模式被稱爲denormalization,並且是使用NoSQL數據庫(如Firebase實時數據庫)時的建議方法。主要的缺點,這是數據複製:因此,例如,當用戶改變他們所選擇的地址,就需要改變:下

  • 用戶下address值,
  • users列表地址。

同樣,如果允許用戶更改他們的用戶名,則需要更新其選擇的地址以及用戶節點下的用戶名。

有關處理此問題的詳細信息,請參閱this answer which explains a number of methods(雖然示例使用JavaScript,但前提條件仍適用)。

+0

謝謝,我會試試這個。我很抱歉從原帖 – JDoe

+0

我剛剛完成創建FirebaseRecyclerAdapter實例的混淆。我懷疑如何訪問用戶映射列出我的onBindViewHolder方法中的用戶。有任何想法嗎? – JDoe

+0

所以你應該可以從'onBindViewHolder()'''''''''''''參數'''''''''''''每個行''地址'模型的一個實例。然後,您可以使用'getUsers()'和[遍歷此映射](https://stackoverflow.com/a/1066607)。例如:'for(String username:model.getUsers.values()){textView.append(username +「&」)}'。 – Grimthorr

2

使用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

+0

我可以問一下構造函數如何成爲public Item? – JDoe

+0

糟糕我的錯誤!我糾正了它。 – Grimthorr

+0

謝謝你的回答:)我會試試 – JDoe