Skip to content

Support for joins #276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 87 commits into from
Nov 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
8b7b4f4
Update FirebaseArray to support joined data
SUPERCILEX Sep 1, 2016
adaebb9
Update FirebaseRecyclerAdapter to support joined data
SUPERCILEX Sep 1, 2016
a176ee5
Refactor setOnChangedListener
SUPERCILEX Sep 1, 2016
01ab8d5
Update FirebaseListAdapter to support joined data
SUPERCILEX Sep 1, 2016
620e8bf
Refactor setOnChangedListener
SUPERCILEX Sep 1, 2016
c5f8d94
Update README.md
SUPERCILEX Sep 1, 2016
34482a3
Handle key not found at dataRef
SUPERCILEX Sep 1, 2016
00e488f
Handle onCancelled
SUPERCILEX Sep 2, 2016
ac217dc
Handle onCancelled
SUPERCILEX Sep 2, 2016
15b8b9b
Handle onCancelled
SUPERCILEX Sep 2, 2016
355d845
Update FirebaseArray.java
SUPERCILEX Sep 2, 2016
b5c132d
Merge remote-tracking branch 'refs/remotes/firebase/master'
SUPERCILEX Sep 2, 2016
723dab2
Update FirebaseArray.java
SUPERCILEX Sep 2, 2016
964ca72
Update FirebaseListAdapter.java
SUPERCILEX Sep 2, 2016
eca10e9
Update FirebaseRecyclerAdapter.java
SUPERCILEX Sep 2, 2016
871aab2
Update FirebaseArray.java
SUPERCILEX Sep 2, 2016
d97bb60
Update FirebaseListAdapter.java
SUPERCILEX Sep 2, 2016
7e2be3a
Log a warning instead of exception if key is missing
SUPERCILEX Sep 6, 2016
8389204
Merge remote-tracking branch 'refs/remotes/origin/master' into fireba…
SUPERCILEX Sep 6, 2016
b002725
Merge pull request #1 from firebase/master
SUPERCILEX Sep 6, 2016
315428d
Merge pull request #4 from firebase/master
SUPERCILEX Sep 9, 2016
b8f3002
Extract indexed array into separate class
SUPERCILEX Sep 10, 2016
3cbadb9
Merge remote-tracking branch 'origin/master' into indexed-database
SUPERCILEX Sep 10, 2016
b08ac51
Fix formatting
SUPERCILEX Sep 10, 2016
336c67e
Fix formatting
SUPERCILEX Sep 10, 2016
96d781b
Fix formatting
SUPERCILEX Sep 10, 2016
d6c70b3
Refactor adapters
SUPERCILEX Sep 10, 2016
696b430
Merge remote-tracking branch 'origin/master' into index
SUPERCILEX Sep 10, 2016
670a3fe
Fix IndexOutOfBoundsException and list item not being removed
SUPERCILEX Sep 11, 2016
69bc97b
Make getIndexForKey available to implementations
SUPERCILEX Sep 11, 2016
96495fe
Code cleanup and optimizations
SUPERCILEX Sep 11, 2016
ea8a46b
Add copyright
SUPERCILEX Sep 11, 2016
c6edad5
Update FirebaseRecyclerAdapter.java
SUPERCILEX Sep 12, 2016
dc37f54
Re-architected IndexFirebaseArray
SUPERCILEX Sep 12, 2016
47ff60a
Fix Intellij's annoying obsession with putting interfaces at the bott…
SUPERCILEX Sep 12, 2016
265d3ce
Update IndexFirebaseArray.java
SUPERCILEX Sep 12, 2016
999cf72
Fix "key not found" exception when a key from the key ref has a null …
SUPERCILEX Sep 12, 2016
e4c3b2d
Extract FirebaseIndexListAdapter
SUPERCILEX Sep 13, 2016
a19160b
Cleanup for final review
SUPERCILEX Sep 13, 2016
dc37cbe
Cleanup for final review
SUPERCILEX Sep 13, 2016
b6013dd
Update FirebaseArray.java
SUPERCILEX Sep 13, 2016
3ec0eb9
Merge pull request #8 from firebase/master
SUPERCILEX Sep 15, 2016
b5666a9
Refactoring of IndexFirebaseArray
MaciejCiemiega Sep 16, 2016
dab8053
Merge remote-tracking branch 'refs/remotes/SUPERCILEX/master'
MaciejCiemiega Sep 16, 2016
32fde6c
Merge branch 'master' into master
MaciejCiemiega Sep 17, 2016
f564c70
Merge branch 'master' of https://github.com/MaciejCiemiega/FirebaseUI…
MaciejCiemiega Sep 17, 2016
e2bf828
Update README.md
SUPERCILEX Sep 17, 2016
059192c
Improved cleanup speed.
SUPERCILEX Sep 17, 2016
1f41ad1
Renames
SUPERCILEX Sep 17, 2016
de3e905
Handle case when dataSnapshot value is null
MaciejCiemiega Sep 18, 2016
e08b67c
Update IndexFirebaseArray.java
SUPERCILEX Sep 18, 2016
7e5a1e2
Merge remote-tracking branch 'remotes/SUPERCILEX/master'
MaciejCiemiega Sep 18, 2016
f8d03f2
Renamed to FirebaseIndexArray
MaciejCiemiega Sep 18, 2016
c1d9c0b
Merge remote-tracking branch 'remotes/SUPERCILEX/master'
MaciejCiemiega Sep 18, 2016
8e68bff
Cleanup
SUPERCILEX Sep 18, 2016
8a3b58f
Fixed condition in isMatch method
MaciejCiemiega Sep 18, 2016
4d9b5d8
Tweaks
SUPERCILEX Sep 18, 2016
7651f28
Add back supers
SUPERCILEX Sep 18, 2016
45b6cff
Update FirebaseArray.java
SUPERCILEX Sep 18, 2016
2461470
Merge pull request #11 from MaciejCiemiega/master
SUPERCILEX Sep 19, 2016
ad50af1
Merge pull request #14 from firebase/master
SUPERCILEX Sep 24, 2016
0e998aa
Merge pull request #19 from firebase/master
SUPERCILEX Sep 30, 2016
e1aaaed
Merge branch 'firebase-master'
SUPERCILEX Oct 4, 2016
dfa4ef3
Merge remote-tracking branch 'origin/master'
SUPERCILEX Oct 4, 2016
a59f25f
Merge branch 'firebase-master'
SUPERCILEX Oct 7, 2016
3d5c59d
Make life compile
SUPERCILEX Oct 7, 2016
b933522
Merge remote-tracking branch 'firebase/master'
SUPERCILEX Oct 8, 2016
52681e1
Merge remote-tracking branch 'origin/master'
SUPERCILEX Oct 8, 2016
630a4f8
Update FirebaseArray.java
SUPERCILEX Oct 8, 2016
a67f5a2
Fix package statements moving around
SUPERCILEX Oct 8, 2016
7b338d0
Merge remote-tracking branch 'origin/master'
SUPERCILEX Oct 8, 2016
7848ffb
Merge remote-tracking branch 'firebase/master'
SUPERCILEX Oct 13, 2016
d877e05
Cleanup
SUPERCILEX Oct 15, 2016
8a55bf8
Merge remote-tracking branch 'firebase/master'
SUPERCILEX Oct 19, 2016
eef20db
Add clearer error logging
SUPERCILEX Oct 19, 2016
c421d83
Updated documentation
SUPERCILEX Oct 19, 2016
e269eb4
Even clearer
SUPERCILEX Oct 19, 2016
4fddf27
Relax query requirements and remove unnecessary constructors.
SUPERCILEX Oct 20, 2016
d6fed13
Merge remote-tracking branch 'origin/master'
SUPERCILEX Oct 20, 2016
8ce38f6
fix typo
SUPERCILEX Oct 20, 2016
20ebddd
tests part 1
SUPERCILEX Oct 21, 2016
645dc05
test travis should fail
SUPERCILEX Oct 21, 2016
5769975
tests part 2
SUPERCILEX Oct 21, 2016
9d8f7f6
Remove unnecessary constructor
SUPERCILEX Oct 28, 2016
eecc8cd
Fix typo
SUPERCILEX Oct 28, 2016
9cdb9ea
Fix nits
SUPERCILEX Oct 31, 2016
c6ca19d
Merge remote-tracking branch 'firebase/version-1.0.0-dev'
SUPERCILEX Nov 1, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions database/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,22 @@ recycler.setAdapter(mAdapter);
```

Like before, we get a custom RecyclerView populated with data from Firebase by setting the properties to the correct fields.

## Using FirebaseUI with indexed data
If your data is [properly indexed](https://firebase.google.com/docs/database/android/structure-data#best_practices_for_data_structure), change your adapter initalization like so:

For a `RecyclerView`, use `FirebaseIndexRecyclerAdapter` instead of `FirebaseRecyclerAdapter`:
```java
new FirebaseIndexRecyclerAdapter<Chat, ChatHolder>(Chat.class,
android.R.layout.two_line_list_item,
ChatHolder.class,
keyRef, // The Firebase location containing the list of keys to be found in dataRef.
dataRef) //The Firebase location to watch for data changes. Each key key found at keyRef's location represents a list item in the RecyclerView.
```

And for a `ListView`, use `FirebaseIndexListAdapter`;
```java
new FirebaseIndexListAdapter<Chat>(this, Chat.class, android.R.layout.two_line_list_item, keyRef, dataRef)
```

`keyRef` is the location of your keys, and `dataRef` is the location of your data.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,79 +18,48 @@
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;

import com.firebase.ui.database.utils.Bean;
import com.google.firebase.FirebaseApp;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;

import junit.framework.AssertionFailedError;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import static com.firebase.ui.database.TestUtils.getAppInstance;
import static com.firebase.ui.database.TestUtils.getBean;
import static com.firebase.ui.database.TestUtils.runAndWaitUntil;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class FirebaseArrayOfObjectsTest extends InstrumentationTestCase {
public static class Bean {
int number;
String text;
boolean bool;

public Bean() {
// necessary for Jackson
}

public Bean(int number, String text, boolean bool) {
this.number = number;
this.text = text;
this.bool = bool;
}
public Bean(int index) {
this(index, "Text "+index, index % 2 == 0);
}

public int getNumber() {
return number;
}

public String getText() {
return text;
}

public boolean isBool() {
return bool;
}
}

private DatabaseReference mRef;
private FirebaseArray mArray;

@Before
public void setUp() throws Exception {
FirebaseApp app = ApplicationTest.getAppInstance(getInstrumentation().getContext());
FirebaseApp app = getAppInstance(getInstrumentation().getContext());
mRef = FirebaseDatabase.getInstance(app).getReference()
.child("firebasearray").child("objects");
mArray = new FirebaseArray(mRef);
mRef.removeValue();
runAndWaitUntil(mArray, mRef, new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
mRef.push().setValue(new Bean(i, "Text " + i, i % 2 == 0 ? true : false), i);
runAndWaitUntil(mArray, new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
mRef.push().setValue(new Bean(i, "Text " + i, i % 2 == 0), i);
}
}
}, new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return mArray.getCount() == 3;
}
}
}
}, new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return mArray.getCount() == 3;
}
}
);
}

Expand All @@ -113,7 +82,7 @@ public void testSize() throws Exception {
@Test
public void testPushIncreasesSize() throws Exception {
assertEquals(3, mArray.getCount());
runAndWaitUntil(mArray, mRef, new Runnable() {
runAndWaitUntil(mArray, new Runnable() {
public void run() {
mRef.push().setValue(new Bean(4));
}
Expand All @@ -124,9 +93,10 @@ public Boolean call() throws Exception {
}
});
}

@Test
public void testPushAppends() throws Exception {
runAndWaitUntil(mArray, mRef, new Runnable() {
runAndWaitUntil(mArray, new Runnable() {
public void run() {
mRef.push().setValue(new Bean(4), 4);
}
Expand All @@ -140,71 +110,32 @@ public Boolean call() throws Exception {

@Test
public void testAddValueWithPriority() throws Exception {
runAndWaitUntil(mArray, mRef, new Runnable() {
runAndWaitUntil(mArray, new Runnable() {
public void run() {
mRef.push().setValue(new Bean(4), 0.5);
}
}, new Callable<Boolean>() {
public Boolean call() throws Exception {
return mArray.getItem(3).getValue(Bean.class).getNumber() == 3 && mArray.getItem(0).getValue(Bean.class).getNumber() == 4;
return mArray.getItem(3).getValue(Bean.class).getNumber() == 3 && mArray.getItem(0)
.getValue(Bean.class)
.getNumber() == 4;
}
});
}

@Test
public void testChangePriorities() throws Exception {
runAndWaitUntil(mArray, mRef, new Runnable() {
runAndWaitUntil(mArray, new Runnable() {
public void run() {
mArray.getItem(2).getRef().setPriority(0.5);
}
}, new Callable<Boolean>() {
public Boolean call() throws Exception {
return getBean(mArray, 0).getNumber() == 3 && getBean(mArray, 1).getNumber() == 1 && getBean(mArray, 2).getNumber() == 2;
return getBean(mArray, 0).getNumber() == 3
&& getBean(mArray, 1).getNumber() == 1
&& getBean(mArray, 2).getNumber() == 2;
//return isValuesEqual(mArray, new int[]{3, 1, 2});
}
});
}

private static boolean isValuesEqual(FirebaseArray array, int[] expected) {
if (array.getCount() != expected.length) return false;
for (int i=0; i < array.getCount(); i++) {
if (!array.getItem(i).getValue(Integer.class).equals(expected[i])) {
return false;
}
}
return true;
}

private Bean getBean(FirebaseArray array, int index) {
return array.getItem(index).getValue(Bean.class);
}

public static void runAndWaitUntil(final FirebaseArray array, Query ref, Runnable task, Callable<Boolean> done) throws InterruptedException {
final java.util.concurrent.Semaphore semaphore = new java.util.concurrent.Semaphore(0);
array.setOnChangedListener(new FirebaseArray.OnChangedListener() {
public void onChanged(EventType type, int index, int oldIndex) {
semaphore.release();
}

@Override
public void onCancelled(DatabaseError databaseError) {
throw new IllegalStateException(databaseError.toException());
}
});
task.run();
boolean isDone = false;
long startedAt = System.currentTimeMillis();
while (!isDone && System.currentTimeMillis() - startedAt < 5000) {
semaphore.tryAcquire(1, TimeUnit.SECONDS);
try {
isDone = done.call();
} catch (Exception e) {
e.printStackTrace();
// and we're not done
}
}
if (!isDone) {
throw new AssertionFailedError();
}
array.setOnChangedListener(null);
}}
}
Loading