![](/img/trans.png)
[英]How can I retrieve data from Firebase Realtime Database in two different activity
[英]How can I query data with different firebase database names?
這是我作為示例給出的 Firebase 數據庫示例。 這里我想把“+90 505 696 1234”值電話號碼用文本的值做為recycler view查詢和排序值。 我只能做到這一點。 但不是我想要的方式。 此電話號碼將具有兩個或多個值。 您可以在數據庫中看到這一點。
“+90 505 696 1234”:“A”和“+90 505 696 1234”:“AA”。 當我質疑這個數字時,我想看到這個數據。 但我無法創建 CategoryItem 類,因為我的數據庫名稱將是可變的。 我不知道該怎么做。 不會有固定的數據庫名稱。 用戶會查詢不同的號碼。 如何為此創建 CategoryItem 類? 如果你能幫忙,我會很高興。 對不起,我的英語不好。
我的 Firebase 數據庫
{
"ContactPhoneNumbers" : {
"-LcaHYcsoGA-VT8yvgGf" : {
"+90 505 696 1234" : "A",
"+90 506 854 2345" : "B",
"+90 530 408 3456" : "C",
"+90 535 966 4567" : "D",
"+90 536 782 5678" : "E",
"+90 546 934 67 89" : "F",
"+905304080001" : "G",
"+905316910002" : "H",
"+905359660003" : "I",
"+905367820004" : "J",
"+905425420005" : "K",
"+905469340006" : "L",
"05056960007" : "M"
},
"-LcaH_gtgarJwbY5-C08" : {
"+90 505 696 1234" : "AA",
"+90 506 854 2345" : "BB",
"+90 530 408 3456" : "CAC",
"+90 535 966 4567" : "AAA",
"+90 536 782 5678" : "CAB",
"+90 546 934 67 89" : "BB",
"+905304080001" : "A",
"+905316910002" : "BBB",
"+905359660003" : "DDD",
"+905367820004" : "EEE",
"+905425420005" : "FFF",
"+905469340006" : "L",
"05056960007" : "M"
}
}
}
我的活動
public class MainActivity extends AppCompatActivity {
EditText Search_Edit_Text;
Button Search_Button;
RecyclerView Search_Contact_List;
DatabaseReference mUserDatabase;
FirebaseRecyclerOptions<CategoryItem> options,options2;
FirebaseRecyclerAdapter<CategoryItem,CategoryViewHolder> adapter;
Query firebaseSearchQuery,asd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("ContactPhoneNumbers");
Search_Edit_Text = (EditText) findViewById(R.id.Search_Edit_Text);
Search_Button = (Button) findViewById(R.id.Search_Button);
Search_Contact_List = (RecyclerView) findViewById(R.id.Search_Contact_List);
Search_Contact_List.setHasFixedSize(true);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getBaseContext(),2);
Search_Contact_List.setLayoutManager(gridLayoutManager);
Search_Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String searchText = Search_Edit_Text.getText().toString().trim();
firebaseUserSearch(searchText);
}
});
}
private void firebaseUserSearch(final String searchText) {
firebaseSearchQuery = mUserDatabase.orderByChild(searchText).startAt("").endAt("" + "\uf8ff");
options2 = new FirebaseRecyclerOptions.Builder<CategoryItem>()
.setQuery(firebaseSearchQuery,CategoryItem.class)
.build();
adapter = new FirebaseRecyclerAdapter<CategoryItem, CategoryViewHolder>(options2) {
@Override
protected void onBindViewHolder(@NonNull final CategoryViewHolder holder, int position, @NonNull final CategoryItem model) {
Toast.makeText(MainActivity.this, model.getName(), Toast.LENGTH_SHORT).show();
}
@NonNull
@Override
public CategoryViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_layout,parent,false);
return new CategoryViewHolder(itemView);
}
};
setCategory();
}
private void setCategory() {
adapter.startListening();
Search_Contact_List.setAdapter(adapter);
}
}
我的分類項目
這段代碼完全是一個例子。 當我將名稱“string”寫為字符串時,我需要在電話號碼中創建一個名稱。 我不要這個。 我想查看對應電話號碼的值。
public class CategoryItem {
public String name ;
public CategoryItem() {
}
public CategoryItem(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
你不能那樣做。 在不知道名稱的情況下不可能獲得特定的密鑰。 您是否使用鍵來索引數據? 如果是這樣,也許不要這樣做,只需在節點中存儲一個索引,這樣您就可以設置最終標題。
我已經玩過這個了。 因為您使用的是動態鍵,所以沒有有效的方法可以使用orderByChild()
來獲得您想要的結果,而不必將整個“ContactPhoneNumbers”節點下載到客戶端設備,然后執行排序和過濾。 另一種方法是保留聯系人的索引。
這僅適用於小型數據集。 當“ContactPhoneNumbers”變大時不要依賴它,因為它會增加您的成本。 每次調用時,您的聯系人數據庫都將被完整下載。
String phoneSearchText = "+90 530 408 3456";
Query q = mUserDatabase.orderByChild(phoneSearchText).startAt("");
當您的數據依賴於動態鍵時,您已經實現了自定義索引實現,而不是使用 RTDB 的內置索引系統(請參閱索引數據)。
您可以在客戶端(更便宜)或服務器端(更易於維護)構建和維護索引。
出於安全性和可維護性的考慮,我將包含一些修改后的代碼,用於基於Cloud Functions for Firebase構建的服務器端實現。
此代碼將生成以下索引,可以查詢電話號碼並包含所有不同的變體。 對“ContactPhoneNumbers”樹所做的任何更改都將自動反映到此索引中。 您應該確保此索引不會被客戶端設備更改。
{
"ContactPhoneNumbersIndex": {
"+90 505 696 1234": {
"-LcaHYcsoGA-VT8yvgGf": "A",
"-LcaH_gtgarJwbY5-C08": "AA"
},
"+90 506 854 2345": {
"-LcaHYcsoGA-VT8yvgGf": "B",
"-LcaH_gtgarJwbY5-C08": "BB"
},
"+90 530 408 3456": {
"-LcaHYcsoGA-VT8yvgGf": "C",
"-LcaH_gtgarJwbY5-C08": "CAC"
},
"+90 535 966 4567": {
"-LcaHYcsoGA-VT8yvgGf": "D",
"-LcaH_gtgarJwbY5-C08": "AAA"
},
"+90 536 782 5678": {
"-LcaHYcsoGA-VT8yvgGf": "E",
"-LcaH_gtgarJwbY5-C08": "CAB"
},
"+90 546 934 67 89": {
"-LcaHYcsoGA-VT8yvgGf": "F",
"-LcaH_gtgarJwbY5-C08": "BB"
},
"+905304080001": {
"-LcaHYcsoGA-VT8yvgGf": "G",
"-LcaH_gtgarJwbY5-C08": "A"
},
"+905316910002": {
"-LcaHYcsoGA-VT8yvgGf": "H",
"-LcaH_gtgarJwbY5-C08": "BBB"
},
"+905359660003": {
"-LcaHYcsoGA-VT8yvgGf": "I",
"-LcaH_gtgarJwbY5-C08": "DDD"
},
"+905367820004": {
"-LcaHYcsoGA-VT8yvgGf": "J",
"-LcaH_gtgarJwbY5-C08": "EEE"
},
"+905425420005": {
"-LcaHYcsoGA-VT8yvgGf": "K",
"-LcaH_gtgarJwbY5-C08": "FFF"
},
"+905469340006": {
"-LcaHYcsoGA-VT8yvgGf": "L",
"-LcaH_gtgarJwbY5-C08": "L"
},
"05056960007": {
"-LcaHYcsoGA-VT8yvgGf": "M",
"-LcaH_gtgarJwbY5-C08": "M"
}
}
}
由於您在數據庫結構中使用推送 ID,下面編寫的函數在包含推送 ID 的級別上運行,對整個組而不是單個條目執行操作。 您可以在此處閱讀函數的文檔並觀看有關該主題的一些Firecast 。
// Import and initialize Cloud Functions and Admin SDKs
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const ADMIN_DB_REF_PHONE_NUMBER_INDEX = admin.database().ref('/ContactPhoneNumbersIndex');
// Add entirely new contact groups to index
exports.contactGroups_created = functions.database.ref('/ContactPhoneNumbers/{groupPushId}')
.onCreate((snapshot, context) => {
const groupId = context.params.groupPushId;
// prepare atomic write
const pendingUpdates = {};
const contactsMap = snapshot.val();
for (const phone in contactsMap) {
if (contactsMap.hasOwnProperty(phone)) {
let name = contactsMap[phone];
// add data to update
pendingUpdates[`${phone}/${groupId}`] = name;
}
}
// commit the update to the index
return ADMIN_DB_REF_PHONE_NUMBER_INDEX.update(pendingUpdates);
});
// Remove deleted contact groups from index
exports.contactGroups_deleted = functions.database.ref('/ContactPhoneNumbers/{groupPushId}')
.onDelete((snapshot, context) => {
const groupId = context.params.groupPushId;
// prepare atomic write
const pendingUpdates = {};
const contactsMap = snapshot.val();
for (const phone in contactsMap) {
if (contactsMap.hasOwnProperty(phone)) {
let name = contactsMap[phone];
// add data to update
pendingUpdates[`${phone}/${groupId}`] = null; // null will delete data at given location
}
}
// commit the update to the index
return ADMIN_DB_REF_PHONE_NUMBER_INDEX.update(pendingUpdates);
});
// Handle contact changes
exports.contactGroups_changed = functions.database.ref('/ContactPhoneNumbers/{groupPushId}')
.onUpdate((change, context) => {
const groupId = context.params.groupPushId;
// prepare atomic write
const pendingUpdates = {};
// prepare changes map
const changeMap = {};
// add before state to changeMap
const beforeContactsMap = change.before.val();
for (const phone in beforeContactsMap) {
if (beforeContactsMap.hasOwnProperty(phone)) {
let name = beforeContactsMap[phone];
changeMap[phone] = { before: name };
}
}
// add after state to changeMap
const afterContactsMap = change.after.val();
for (const phone in afterContactsMap) {
if (afterContactsMap.hasOwnProperty(phone)) {
let name = afterContactsMap[phone];
if (changeMap[phone]) {
changeMap[phone].after = name;
} else {
changeMap[phone] = { after: name };
}
}
}
// look for changes and commit any differences
for (const phone in changeMap) {
if (changeMap.hasOwnProperty(phone)) {
let nameChange = changeMap[phone];
if (nameChange.before != nameChange.after) {
// changed
pendingUpdates[`${phone}/${groupId}`] = nameChange.after || null; // use updated value or fallback to null to delete
}
}
}
// commit the update to the index
return ADMIN_DB_REF_PHONE_NUMBER_INDEX.update(pendingUpdates);
});
對於您的數據庫結構,創建類是一項艱巨的任務。 一種方法是在節點樹上進一步查看組中的聯系人,您可以在其中圍繞值的內部映射或 Contact 對象列表包裝一個類。
我在下面給出的示例維護內部映射並與之交互。
不幸的是,Firebase SDK 沒有公開類似於自定義比較函數的“序列化”方法,因此您將無法直接將此類與SetValue
和GetValue
一起使用。
上傳到數據庫:
ContactGroup mContacts = ...
DatabaseReference groupRef = mContactGroupsReference.push();
mContacts.setId(groupRef.getKey()); // optional
groupRef.SetValue(mContacts.toMap());
從數據庫下載:
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
ContactGroup contacts = new ContactGroup(dataSnapshot);
// or
ContactGroup contacts = new ContactGroup(dataSnapshot.getKey(), dataSnapshot.getValue());
}
這個類是不完整的。 有足夠的讓果汁流動,但還有很大的改進空間。
public class ContactGroup {
private id = null;
private Map<String, String> contactMap = new HashMap<>(); // Phone => Name
public ContactGroup() {
}
public ContactGroup(String id, Map<String, Object> contacts) {
this.id = id;
if (contacts == null)
return;
for (Map.Entry<String, Object> entry : contacts.entrySet()) {
contactMap.put(entry.getKey(), entry.getValue().toString());
}
}
public ContactGroup(DataSnapshot snapshot) {
this(snapshot.getKey(), snapshot.getValue());
// do something else with snapshot? save the ref?
}
public void add(String name, String phone) {
contactMap.put(phone, name);
}
public String getNameForPhone(String phone) {
return contactMap.get(phone);
}
public String getPhoneForName(String name) {
for (Map.Entry<String, String> entry : contactMap.entrySet()) {
if (entry.getValue() == name)
return entry.getKey();
}
return null;
}
public getId() {
return id;
}
public setId() {
return id;
}
@Exclude
public static ContactGroup fromMap(Map<String, Object> valueMap) {
return new ContactGroup(null, valueMap);
}
@Exclude
public Map<String, Object> toMap() {
return new HashMap<String, Object>(contactMap);
}
}
這里有很多東西要解開(這就是為什么你的問題被否決了,在未來更具體)。 祝你好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.