-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add a callback in FirebaseIndexArray when a Key doesn't exist in a ref #448
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
Conversation
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
|
|
||
| import com.google.firebase.database.DataSnapshot; | ||
|
|
||
| interface OnIndexMismatchListener { |
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.
Remove the On prefix, to align with existing Firebase listeners: ValueEventListener, ChildEventListener.
I'm not really convinced of this class name. It's very specific to this use-case, while we might uncover other use-cases in the future that could use this same interface. If the snapshot is from the originating/key collection, I can see this interface defining a "join this data" contract.
Could we change the behavior from an error to an "override point". So instead of this being the error condition, make it the regular handler for joins? interface JoinResolver, that developers can then implement/override to have their own join/error handling? Thoughts? @SUPERCILEX @samtstern @morganchen12
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.
@puf, so were you thinking of something like this:
@Override
public void onChildAdded(DataSnapshot keySnapshot, String previousChildKey) {
// ...
Query ref = mJoinResolver.onJoin(keySnapshot); // Get the data ref
mRefs.put(ref, ref.addValueEventListener(new DataRefListener()));
}
@Override
public void onChildRemoved(DataSnapshot keySnapshot) {
Query removeQuery = mJoinResolver.onDisjoin(keySnapshot); // Get the remove ref
removeQuery.removeEventListener(mRefs.remove(removeQuery));
// ...
}private class DataRefListener implements ValueEventListener {
@Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.getValue() != null) {
// ...
} else {
if (isMatch(index, key)) {
// ...
} else {
mJoinResolver.onJoinFailed(index, snapshot); // notify 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.
Yup. That first snippet looks like it. Not sure about the second snippet though. What would the mJoinResolver consist of there?
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.
@puf the second snippet is occurs when dataRef returns a null snapshot. The original purpose of this PR was to change that piece of code from a log (Log.w(TAG, "Key not found at ref: " + snapshot.getRef());) to a callback. Is it still okay to follow through with mJoinResolver.onJoinFailed(index, snapshot);?
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
SUPERCILEX
left a comment
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.
@puf It turned out to be more complicated than I thought so this PR is pretty big now, sorry.
I found out today that you can't pass in this while initializing a super constructor. Because of this I had to follow the setter pattern for JoinResolver, but this makes future open sourcing of FirebaseIndexArray and any current implementations unacceptable because people will think that setting a JoinResolver is optional and we would not be able to get the join query. Also, how do we know an onChildAdded event won't be called between the time when we start listening for event and when the JoinResolver is set? To solve this problem, I pretty significantly changed FirebaseArray and FirebaseIndexArray's apis (thank the api god we didn't open source FirebaseArray yet! 😄). Both FirebaseArray and FirebaseIndexArray now follow a start stop pattern like the activity lifecycle: you create stuff and then tear it down. In addition, listeners are no longer optional because a FirebaseArray that never reports back its results is pointless. I made what I believe to be a really nice api (@puf I'd love your thoughts on this!) where you can setup your listeners and then start listening for events once your ready. If you so choose, you may also stop listening for events in effect resetting FirebaseArray. However, the listeners and queries are still present which enables resuming listening at a later time. To prevent errors, all of this is cross checked.
I think my changes make FirebaseArray and FirebaseIndexArray much more ready for open sourcing with nicer apis, @puf what are your thoughts on these changes?
| @@ -0,0 +1,41 @@ | |||
| package com.firebase.uidemo.database; | |||
|
|
|||
| public class Chat { | |||
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 extracted Chat and ChatHolder to simplify ChatActivity.
| chatView.setName(chat.getName()); | ||
| chatView.setText(chat.getMessage()); | ||
| mRecyclerViewAdapter = | ||
| new FirebaseIndexRecyclerAdapter<Chat, ChatHolder>( |
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.
Because FirebaseIndexRecyclerAdapter is slightly more complicated and less documented, I think we should demo that in the sample.
| attachRecyclerViewAdapter(); | ||
| } | ||
| }) | ||
| .addOnCompleteListener(new OnCompleteListener<AuthResult>() { |
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.
Making the Toast survive activity rotation.
| */ | ||
| class FirebaseArray implements ChildEventListener { | ||
| public interface OnChangedListener { | ||
| public interface ChangeEventListener { |
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.
Changed the name to follow ChildEventListener.
| } | ||
|
|
||
| public int getCount() { | ||
| public int size() { |
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.
Changed getCount and getItem to follow array naming conventions.
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.
These look like pretty breaking changes, but I'm only just someone really curious about this project.
Also, was a consensus ever reached on using enums in the code? Shouldn't we be doing something like this:
public interface ChangeListener {
public static class EventType {
public static final int ADDED = 1;
public static final int CHANGED = 2;
// ...
}
}
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.
@TheCraftKid Nope, these aren't breaking api changes. 🎉 We're really lucky @puf wanted to hold out on open sourcing FirebaseArray and FirebaseIndexArray or these would have been (You're thinking of FirebaseRecyclerViewAdapter#getItemCount(), but I didn't change that.)
As for enums, @puf decided against it and I'm fine with that because I found out proguard usually converts enums to ints anyway: http://stackoverflow.com/a/32236950/4548500. Cheers!
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.
Well, then.
Wait, FirebaseArray is being open-sourced? How will that work? Will I finally be able to implement a proper FirebaseSpinnerAdapter?
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.
Woah woah woah! 😄 I was just saying that eventually @puf will have to open source it (technically he doesn't, but come on!). I think he was waiting for some additional refinement and this PR + another one I have ready will clean things up a bit, making it more likely that FirebaseArray will be open sourced. Then yes, you will finally be able to implement a proper FirebaseSpinnerAdapter!
| super.setChangeEventListener(mListenerCopy); | ||
|
|
||
| Query ref = mQuery.getRef().child(keySnapshot.getKey()); | ||
| Query ref = mJoinResolver.onJoin(keySnapshot, previousChildKey); |
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.
Using the new JoinResolver.
| Query keyRef, | ||
| Query dataRef) { | ||
| super(modelClass, modelLayout, viewHolderClass, new FirebaseIndexArray(keyRef, dataRef)); | ||
| super(modelClass, modelLayout, viewHolderClass, new FirebaseIndexArray(keyRef), false); |
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.
Sadly, I can't just pass in new FirebaseIndexArray(keyRef, this).
| import com.google.firebase.database.DataSnapshot; | ||
| import com.google.firebase.database.Query; | ||
|
|
||
| public interface JoinResolver { |
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.
Thoughts on the documentation?
|
Uhm.... I'm confused. FirebaseArray is just as open-source as the rest of
FirebaseUI-Android. If you're interested in how it works, you can admire
all 12 lines of it here:
https://github.com/firebase/FirebaseUI-Android/blob/master/database/src/main/java/com/firebase/ui/database/FirebaseArray.java
.
…On Sun, Dec 18, 2016 at 9:00 PM Alex Saveau ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In database/src/main/java/com/firebase/ui/database/FirebaseArray.java
<#448>:
> }
- public int getCount() {
+ public int size() {
Woah woah woah! 😄 I was just saying that eventually @puf
<https://github.com/puf> will have to open source it (technically he
doesn't, but come on!). I think he was waiting for some additional
refinement and this PR + another one I have ready will clean things up a
bit, making it more likely that FirebaseArray will be open sourced. Then
yes, you will finally be able to implement a proper FirebaseSpinnerAdapter
!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#448>, or mute the
thread
<https://github.com/notifications/unsubscribe-auth/AA3w31wWJpFHYOD3A8Z6nIRWgU18I5v5ks5rJg-IgaJpZM4LIlIo>
.
|
|
@puf I meant making |
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
…lback # Conflicts: # app/src/main/java/com/firebase/uidemo/database/ChatActivity.java # 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
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
# Conflicts: # database/src/androidTest/java/com/firebase/ui/database/TestUtils.java
…lback # Conflicts: # app/src/main/java/com/firebase/uidemo/database/ChatActivity.java # database/src/androidTest/java/com/firebase/ui/database/TestUtils.java # database/src/main/java/com/firebase/ui/database/FirebaseArray.java # database/src/main/java/com/firebase/ui/database/FirebaseIndexArray.java # database/src/main/java/com/firebase/ui/database/FirebaseListAdapter.java # database/src/main/java/com/firebase/ui/database/FirebaseRecyclerAdapter.java
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
…lback # Conflicts: # app/src/main/java/com/firebase/uidemo/database/ChatActivity.java # database/src/androidTest/java/com/firebase/ui/database/FirebaseArrayOfObjectsTest.java # database/src/androidTest/java/com/firebase/ui/database/FirebaseArrayTest.java # database/src/androidTest/java/com/firebase/ui/database/FirebaseIndexArrayOfObjectsTest.java # database/src/androidTest/java/com/firebase/ui/database/FirebaseIndexArrayTest.java # database/src/androidTest/java/com/firebase/ui/database/TestUtils.java # database/src/main/java/com/firebase/ui/database/FirebaseArray.java # database/src/main/java/com/firebase/ui/database/FirebaseIndexArray.java # database/src/main/java/com/firebase/ui/database/FirebaseIndexRecyclerAdapter.java # database/src/main/java/com/firebase/ui/database/FirebaseListAdapter.java # database/src/main/java/com/firebase/ui/database/FirebaseRecyclerAdapter.java
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
|
So there's good news and bad news. 👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there. 😕 The bad news is that it appears that one or more commits were authored by someone other than the pull request submitter. We need to confirm that they're okay with their commits being contributed to this project. Please have them confirm that here in the pull request. Note to project maintainer: This is a terminal state, meaning the |
|
CLAs look good, thanks! |
|
@samtstern Should we add extra constructors in the index adapters? I feel like this is a niche feature and people who use it will know how to pass in a |
…lback # Conflicts: # database/src/main/java/com/firebase/ui/database/FirebaseIndexArray.java
…lback # Conflicts: # database/src/main/java/com/firebase/ui/database/FirebaseIndexArray.java
|
@samtstern While we're on the merge rollercoaster, I think this one is the next PR to take a look at. 😄 |
|
@SUPERCILEX I agree, this one is definitely next. I will take a look tomorrow. A lot has changed in how we handle the IndexedArray (and really everything) since this was first sent out. Btw we really appreciate that you always keep these PRs up to date and you're ready to discuss when we find the time. It's above-and-beyond as a contributor and arguably we have not earned it since we go radio silent too often. |
|
@samtstern No problem, I'm just happy whenever the ball moves forward a bit! 😄 Yeah, this was actually the PR that got me started on the whole "Let's redo |
|
Going to close this PR since there is very little demand and it isn't on the FirebaseUI roadmap. |
#441
@puf Please review.