-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Support for joins #276
Conversation
# Conflicts: # database/src/main/java/com/firebase/ui/database/FirebaseArray.java # database/src/main/java/com/firebase/ui/database/FirebaseListAdapter.java # database/src/main/java/com/firebase/ui/database/FirebaseRecyclerAdapter.java
I'm waiting for this deloy. 👍 |
Hey Alex. Thanks for the PR. Looks great, definitely a very clean implementation of attaching and detaching the listeners. I also like that it uses the data model from the Firebase documentation as its basis. I don't think we should add this code to the basic FirebaseXxxAdapters though. Scanning your code structure I see many Can you see if you can isolate the behavior in separate sub-adapters? |
public DataSnapshot getItem(int index) { | ||
return mSnapshots.get(index); | ||
} | ||
|
||
protected DataSnapshot internalGetItem(int index) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is completely gross IMO, but I don't know how to get rid of it. Any feedback is welcome!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I'll brood on a better way to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found a bug here. When you remove the last element of the list, remove trigger events before and list have no element. So it would make an exception:
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.firebase.ui.database.FirebaseArray.internalGetItem(FirebaseArray.java:61)
at com.firebase.ui.database.FirebaseIndexArray.notifyChangedListeners(FirebaseIndexArray.java:119)
at com.firebase.ui.database.FirebaseArray.notifyChangedListeners(FirebaseArray.java:119)
at com.firebase.ui.database.FirebaseArray.onChildRemoved(FirebaseArray.java:100)
at com.firebase.ui.database.FirebaseIndexArray.onChildRemoved(FirebaseIndexArray.java:29)
at com.google.android.gms.internal.zzahe.zza(Unknown Source)
at com.google.android.gms.internal.zzaje.zzcta(Unknown Source)
at com.google.android.gms.internal.zzajh$1.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5727)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
because mSnapshots.remove(index)
was call before notifyChangedListeners
@Override
public void onChildRemoved(DataSnapshot snapshot) {
int index = getIndexForKey(snapshot.getKey());
mSnapshots.remove(index);
notifyChangedListeners(OnChangedListener.EventType.Removed, index);
}
More seriously, your code is removed mistakenly listener. :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for catching that!!! I completely messed up removing an item: mSnapshots.remove(index)
wasn't even getting called! Check it out now: https://github.com/firebase/FirebaseUI-Android/pull/276/files#diff-c7d9ac7c32439f20359555e3db253268R119
Thanks a ton for the feedback!!! I'm new to the object oriented thing and to programming in general so this was a huge help (and a bit of a struggle). I just figured how to use interfaces to get rid of Anyway, thanks again. I think I have a nice implementation now. Also, I left a question/comment if you have any thoughts about it. |
Should I update the app example to index the data? I don't think it's necessary, but it would put people on the right track for scalability. |
} | ||
index++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert this change please.
public void onCancelled(DatabaseError error) { | ||
Log.e(TAG, "A fatal error occur retrieving the necessary keys to poplulate your adapter"); | ||
super.onCancelled(error); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I should add that invalidating the whole object feels kind of gross, since the dev who encounters this error basically has the options of giving up or creating another indexed array and hoping that one doesn't error. It's like a failable initializer, but in this case the failure is asynchronous and therefore extremely nasty.
If you have ideas for better handling this error, please do share them!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Devs can override this method in which they could reinitialize their adapter with a new ref or replace their view with an "Oops, an unexpected error occurred." message. I think this gives devs nice options. What do you think of having a separate error method to override for the key failure vs the ref failure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think we've done what we can to avoid badness here. How you handle other errors I'll leave to you since I don't know the platform specifics well, but imo they should be passed up to the API consumer with enough info for them to make a good decision.
@morganchen12 @samtstern |
We've got a problem. The database tests aren't running at all and haven't ever been. Is this on purpose? |
I've run the database test locally, manually when we just started the project. They've never been run automatically afaik. |
@puf So as long as the tests ran fine for me, we're good? I got all greens so unless you guys have a few final comments, this PR is good to merge! |
I wouldn't mind them running in CI. We just never had CI when we started. On Thu, Oct 20, 2016 at 5:51 PM Alex Saveau [email protected]
|
I'm pretty sure we'd need an emulator with the current state of the tests which would significantly slow Travis down. |
public void onChildMoved(DataSnapshot snapshot, String previousChildKey) { | ||
int oldIndex = getIndexForKey(snapshot.getKey()); | ||
mSnapshots.remove(oldIndex); | ||
int newIndex = previousChildKey == null ? 0 : (getIndexForKey(previousChildKey) + 1); | ||
int newIndex = previousChildKey == null ? 0 : getIndexForKey(previousChildKey) + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please put back the parentheses around (getIndexForKey(previousChildKey) + 1)
. The behavior is the same, but it makes the intent more explicit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
mListener = listener; | ||
} | ||
|
||
private class DataRefSnapshot implements ValueEventListener { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should name this class to indicate that it's a listener.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed it DataRefListener
, what do you think?
I had a few nits, aside from that this looks good to me. Thanks for all the hard work on this! |
@puf @samtstern firebase/FirebaseUI-iOS#164 was just merged, any idea when this PR will be merged? |
@SUPERCILEX can you edit this PR to target the 1.0 branch? Once that's done and tests pass/conflicts are resolved I'll merge |
No conflicts!!! @morganchen12 This is awesome!!! I finally get to delete my |
@SUPERCILEX two months later it's in! Thank you for your patience and all the other contributions you made while this one was pending. Version 1.0.0 is getting very close, excited to see this live. |
TODO: