Ich arbeite an Android mit Firebase. Ich möchte eine Liste von Informationen mit einem ArrayAdapter aus einer Datenbank anzeigen. Ich benutze eine ArrayList von Uids. einige Benutzerinformationen von einer denormalized Feuerbasis Datenbank zu holen, wie so strukturiert:Anzeige von Daten aus mehreren Firebase-Datenbankreferenzen mit einem ArrayAdapter
name : {
uid1:"bear",
uid2:"salmon"
},
phone : {
uid1:"888-395-4023",
uid2:"123-456-6789"
}
Mein aktueller Ansatz ist die abgerufenen Werte in ein Userinfo Objekt einer Klasse wie folgt zu speichern.
public UserInfo (String name, String phone)
und fügen Sie dann jedes Objekt zum ArrayAdapter hinzu.
someArrayAdapter.add(userInfo);
Mein Problem ist, mit mehr als einem Benutzer und Lesen von Daten von mehr als einer Referenz, in der meine folgende Umsetzung alle Felder in der zugegebenen userinfo sind leer, weil Ereignis-Listener-Rückrufe nach der Methode add() empfangen werden Anruf (Daten nicht aktualisiert wird, wenn die Rückrufe empfangen werden)
private FirebaseDatabase mFirebaseDatabase = new FirebaseDatabase.getInstance();
private ValueEventListener mNameListener;
private ValueEventListener mPhoneListener;
private DatabaseReference mNameRef;
private DatabaseReference mPhoneRef;
private void getUserInfo (@NonNull final ArrayList<String> uidList)
{
// This for-loop loops through the list of strings, and use the string to construct new database references.
for (String uid : uidList)
{
// Create a new userInfo object
UserInfo userInfo = new UserInfo();
// Create a database reference for accessing the name
mNameRef = mFirebaseDatabase.getReference().child("name").child(uid);
// Create a database reference for accessing the name
mPhoneRef = mFirebaseDatabase.getReference().child("phone").child(uid);
// My name listener
mNameListener = new ValueEventListener()
{
@Override
public void onDataChange(final DataSnapshot dataSnapshot) {
String name = DataSnashot.getValue().toString();
userInfo.setName(name);
}
// ...skipped irrelevant override
}
// My phone listener
mPhoneListener = new ValueEventListener()
{
@Override
public void onDataChange(final DataSnapshot dataSnapshot) {
String phone = DataSnashot.getValue().toString();
userInfo.setPhone(phone);
// Log to try getting the phone from the object, as expected, is good
Log.i(TAG, userInfo.getPhone());
}
// ...skipped irrelevant override
}
// Attach the listeners
mNameRef.addListenerForSingleValueEvent(mNameListener);
mPhoneRef.addListenerForSingleValueEvent(mPhoneListener);
// Problem here: listener callbacks are received after this method fires.
someArrayAdapter.add(userInfo);
// Log, returns empty for both fields, and this log message runs before the callback log messages above.
Log.i(TAG, userInfo.getName() + " " + userInfo.getPhone());
}
}
ich haben will ein „vollständig“ userinfo Objekt vor der for-Schleife auf die nächste uid geht. Und, wie sollte ich verwalten, damit der Adapter das userInfo Objekt nur hinzufügt, wenn alle Rückrufe empfangen werden?
Ich brauche auf jeden Fall einen besseren Weg, um die Daten persistent zu machen, aber so wie es aussieht, ist es viel einfacher für die Wartung, wenn ich einfach mit einfachen Objekten umgehen kann. Vielen Dank für Ihre Hilfe und Zeit, und bitte verzeihen Sie mir für jede Syntax oder fehlende ";" Probleme, ich habe nicht den Beispielcode auf eine IDE geschrieben :)
Danke für den Kommentar, aber ich denke nicht, dass Ihr Ansatz im Maßstab funktioniert.Was die Datenbankstruktur anbelangt, befolge ich die Best Practice gemäß Firebase Docs zur Denormalisierung. Meine aktuelle Datenbank hat 14 separate Benutzerfelder. Wenn ich alle zusammen durcheinander bringe, wird die Suche nach einer passenden UID mit nur einer Information sehr lange dauern. –
Angesichts der Struktur wie gezeigt, aber was ist, wenn ein Benutzer keinen Namen hat, aber eine Telefonnummer hat? Der Telefonhörer und anschließend der someAdapater werden überhaupt nicht ausgelöst –
Das ist immer noch in Ordnung. Seit Firebase ist Schema weniger. Du kannst das. Userinfo userinfo = Neue UserInfo (Name). Haben Sie einfach einen Konstruktor, der nur den Namen annimmt, und Sie können diese Benutzerinformation immer noch unter den gleichen Knoten setzen –