Created
July 10, 2016 22:06
-
-
Save remcomokveld/09b111e54dfc9cd8c0fc9a4d9c3bd63b to your computer and use it in GitHub Desktop.
FirebaseLoaders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package nl.remcomokveld.firebaseloaders; | |
import android.content.Context; | |
import android.support.annotation.NonNull; | |
import android.support.v4.content.Loader; | |
import com.google.firebase.database.DataSnapshot; | |
import com.google.firebase.database.DatabaseError; | |
import com.google.firebase.database.DatabaseReference; | |
import com.google.firebase.database.ValueEventListener; | |
public class FirebaseItemLoader<Type> extends Loader<Type> implements ValueEventListener { | |
private final DatabaseReference databaseReference; | |
private final SnapshotAdapter<Type> snapshotAdapter; | |
public FirebaseItemLoader(@NonNull Context context, | |
@NonNull DatabaseReference databaseReference, | |
@NonNull SnapshotAdapter<Type> snapshotAdapter) { | |
super(context); | |
this.databaseReference = databaseReference; | |
this.snapshotAdapter = snapshotAdapter; | |
} | |
@Override | |
protected void onStartLoading() { | |
super.onStartLoading(); | |
databaseReference.addValueEventListener(this); | |
} | |
@Override | |
protected void onStopLoading() { | |
super.onStopLoading(); | |
databaseReference.removeEventListener(this); | |
} | |
@Override | |
public void onDataChange(DataSnapshot dataSnapshot) { | |
deliverResult(snapshotAdapter.adapt(dataSnapshot)); | |
} | |
@Override | |
public void onCancelled(DatabaseError databaseError) { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package nl.remcomokveld.firebaseloaders; | |
import android.content.Context; | |
import android.support.annotation.NonNull; | |
import android.support.annotation.Nullable; | |
import android.support.v4.content.Loader; | |
import com.google.firebase.database.ChildEventListener; | |
import com.google.firebase.database.DataSnapshot; | |
import com.google.firebase.database.DatabaseError; | |
import com.google.firebase.database.DatabaseReference; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
public class FirebaseListLoader<Type> extends Loader<List<Type>> implements ChildEventListener { | |
private final SnapshotAdapter<Type> snapshotAdapter; | |
private final DatabaseReference mDatabaseReference; | |
/** Both a List and a HashMap are used for storing references to the result because | |
* the list allows keeping the data sorted and the Map allows O(n) access times when updating | |
* or deleting data | |
*/ | |
List<Item> mItems = new ArrayList<>(); | |
Map<String, Item> mItemMap = new HashMap<>(); | |
public FirebaseListLoader(@NonNull Context context, | |
@NonNull DatabaseReference databaseReference, | |
@NonNull SnapshotAdapter<Type> snapshotAdapter) { | |
super(context); | |
this.snapshotAdapter = snapshotAdapter; | |
this.mDatabaseReference = databaseReference; | |
} | |
@Override | |
protected void onStartLoading() { | |
super.onStartLoading(); | |
mDatabaseReference.addChildEventListener(this); | |
} | |
@Override | |
protected void onStopLoading() { | |
super.onStopLoading(); | |
mDatabaseReference.removeEventListener(this); | |
} | |
@Override | |
public void onChildAdded(DataSnapshot dataSnapshot, String s) { | |
if (mItemMap.containsKey(dataSnapshot.getKey())) return; | |
Type appWrapper = snapshotAdapter.adapt(dataSnapshot); | |
Item newItem = new Item(dataSnapshot.getKey(), appWrapper, s); | |
mItems.add(newItem); | |
mItemMap.put(newItem.key, newItem); | |
updateResult(); | |
} | |
private void updateResult() { | |
Collections.sort(mItems); | |
ArrayList<Type> types = new ArrayList<>(mItems.size()); | |
for (Item item : mItems) { | |
types.add(item.value); | |
} | |
deliverResult(types); | |
} | |
@Override | |
public void onChildChanged(DataSnapshot dataSnapshot, String s) { | |
mItemMap.get(dataSnapshot.getKey()).value = snapshotAdapter.adapt(dataSnapshot); | |
updateResult(); | |
} | |
@Override | |
public void onChildRemoved(DataSnapshot dataSnapshot) { | |
Item item = mItemMap.get(dataSnapshot.getKey()); | |
mItems.remove(item); | |
updateResult(); | |
} | |
@Override | |
public void onChildMoved(DataSnapshot dataSnapshot, String s) { | |
Item item = mItemMap.get(dataSnapshot.getKey()); | |
item.previousKey = s; | |
updateResult(); | |
} | |
@Override | |
public void onCancelled(DatabaseError databaseError) { | |
} | |
private class Item implements Comparable<Item> { | |
@NonNull private String key; | |
@Nullable private String previousKey; | |
@NonNull private Type value; | |
public Item(@NonNull String key, @NonNull Type value, @Nullable String previousKey) { | |
this.key = key; | |
this.previousKey = previousKey; | |
this.value = value; | |
} | |
@Override | |
public int compareTo(@NonNull Item item) { | |
if (previousKey == null || key.equals(item.previousKey)) return -1; | |
if (item.key.equals(previousKey)) return 1; | |
return 0; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private static class AppSnapshotAdapter implements SnapshotAdapter<SampleValueObject> { | |
@Override | |
public SampleValueObject adapt(DataSnapshot dataSnapshot) { | |
return new SampleValueObject(dataSnapshot); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private static class SampleValueObject { | |
private final DataSnapshot dataSnapshot; | |
public SampleValueObject(DataSnapshot dataSnapshot) { | |
this.dataSnapshot = dataSnapshot; | |
} | |
@Override | |
public String getId() { | |
return dataSnapshot.getKey(); | |
} | |
@Override | |
public String getName() { | |
return dataSnapshot.child("name").getValue(String.class); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package nl.remcomokveld.firebaseloaders; | |
import com.google.firebase.database.DataSnapshot; | |
public interface SnapshotAdapter<Type> { | |
Type adapt(DataSnapshot dataSnapshot); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment