Skip to content

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

Closed
wants to merge 47 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
28c366c
Add a callback in FirebaseIndexArray when a Key doesn't exist in a ref
SUPERCILEX Dec 9, 2016
641297c
Add documentation
SUPERCILEX Dec 9, 2016
a62a025
Rename listeners
SUPERCILEX Dec 14, 2016
703f85d
Merge remote-tracking branch 'firebase/version-1.1.0-dev' into db-cal…
SUPERCILEX Dec 14, 2016
f1e702b
Add JoinResolver.java interface
SUPERCILEX Dec 15, 2016
af39a1e
Cleanup
SUPERCILEX Dec 15, 2016
25fc4df
Rename ChangeListener to ChangeEventListener
SUPERCILEX Dec 15, 2016
5486e8c
Cleanup
SUPERCILEX Dec 15, 2016
23806d7
Make JoinResolver.java public
SUPERCILEX Dec 15, 2016
06fb7d0
Merge remote-tracking branch 'firebase/version-1.1.0-dev' into db-cal…
SUPERCILEX Dec 16, 2016
0b56e99
Merge remote-tracking branch 'firebase/version-1.1.0-dev' into db-cal…
SUPERCILEX Dec 22, 2016
331b4bf
Rename
SUPERCILEX Jan 3, 2017
f396fec
Merge remote-tracking branch 'firebase/version-1.1.0-dev' into db-cal…
SUPERCILEX Jan 3, 2017
cfdb305
Fix compile error
SUPERCILEX Jan 3, 2017
cc3729c
Merge branch 'version-1.1.0-dev' into db-callback
SUPERCILEX Jan 5, 2017
f5d06b2
Merge remote-tracking branch 'firebase/version-1.1.0-dev' into db-cal…
SUPERCILEX Jan 9, 2017
de52c1d
Merge remote-tracking branch 'firebase/version-1.1.0-dev' into db-cal…
SUPERCILEX Jan 11, 2017
97d9cb0
Fix merge mistakes
SUPERCILEX Jan 11, 2017
e7297d4
Merge remote-tracking branch 'firebase/master' into db-callback
SUPERCILEX Jan 13, 2017
9a03342
Merge remote-tracking branch 'firebase/master' into db-callback
SUPERCILEX Jan 17, 2017
8f87492
Merge branch 'version-1.2.0-dev' of https://github.com/firebase/Fireb…
SUPERCILEX Jan 22, 2017
dcf96bf
Merge remote-tracking branch 'firebase/version-1.2.0-dev' into db-cal…
SUPERCILEX Jan 25, 2017
48ea75a
Fix a ton of merge mistakes
SUPERCILEX Jan 25, 2017
4a5a1be
Provide default join resolver
SUPERCILEX Jan 25, 2017
dbbf0dc
Fix tests and bugs
SUPERCILEX Jan 25, 2017
b37c8bd
Cleanup
SUPERCILEX Jan 25, 2017
d25245b
More cleanup
SUPERCILEX Jan 25, 2017
7e01eb1
Fix spacing
SUPERCILEX Jan 25, 2017
f09383f
Merge remote-tracking branch 'firebase/version-2.0.0-dev' into db-cal…
SUPERCILEX Mar 6, 2017
03c14d2
Fix merge mistakes
SUPERCILEX Mar 6, 2017
63d5ca5
Fixups
SUPERCILEX Mar 6, 2017
14e3443
Merge remote-tracking branch 'firebase/version-2.0.0-dev' into db-cal…
SUPERCILEX Mar 6, 2017
ab613bd
Cleanup
SUPERCILEX Mar 10, 2017
64bfb37
Merge remote-tracking branch 'firebase/version-2.0.0-dev' into db-cal…
SUPERCILEX Mar 10, 2017
ae83d83
Merge remote-tracking branch 'firebase/version-2.0.0-dev' into db-cal…
SUPERCILEX Mar 13, 2017
371c211
Cleanup
SUPERCILEX Mar 14, 2017
dbc1a43
Merge remote-tracking branch 'firebase/version-2.0.0-dev' into db-cal…
SUPERCILEX Mar 14, 2017
0a1d2b5
Merge remote-tracking branch 'upstream/version-2.0.0-dev' into db-cal…
SUPERCILEX Apr 24, 2017
53920a2
Merge remote-tracking branch 'upstream/version-2.0.0-dev' into db-cal…
SUPERCILEX Apr 26, 2017
b3c137f
Flip onJoinFailed params to make more sense
SUPERCILEX Apr 26, 2017
c23eec1
Merge remote-tracking branch 'upstream/version-2.0.0-dev' into db-cal…
SUPERCILEX May 2, 2017
d2962fa
Merge remote-tracking branch 'upstream/version-2.0.0-dev' into db-cal…
SUPERCILEX May 9, 2017
52b7c10
Merge remote-tracking branch 'upstream/version-2.0.0-dev' into db-cal…
SUPERCILEX May 13, 2017
f236047
Merge remote-tracking branch 'upstream/version-2.0.0-dev' into db-cal…
SUPERCILEX Jun 2, 2017
2933598
Merge remote-tracking branch 'upstream/version-2.0.0-dev' into db-cal…
SUPERCILEX Jun 5, 2017
a2909e4
Merge remote-tracking branch 'upstream/version-2.0.0-dev' into db-cal…
SUPERCILEX Jun 9, 2017
a11975c
Merge remote-tracking branch 'upstream/master' into db-callback
SUPERCILEX Jun 12, 2017
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
41 changes: 41 additions & 0 deletions app/src/main/java/com/firebase/uidemo/database/Chat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.firebase.uidemo.database;

public class Chat {
Copy link
Collaborator Author

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.

private String mName;
private String mMessage;
private String mUid;

public Chat() {
// Needed for Firebase
}

public Chat(String name, String message, String uid) {
mName = name;
mMessage = message;
mUid = uid;
}

public String getName() {
return mName;
}

public void setName(String name) {
mName = name;
}

public String getMessage() {
return mMessage;
}

public void setMessage(String message) {
mMessage = message;
}

public String getUid() {
return mUid;
}

public void setUid(String uid) {
mUid = uid;
}
}
188 changes: 52 additions & 136 deletions app/src/main/java/com/firebase/uidemo/database/ChatActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,22 @@

package com.firebase.uidemo.database;

import android.graphics.PorterDuff;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.RotateDrawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.firebase.ui.database.FirebaseIndexRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.uidemo.R;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
Expand All @@ -50,6 +43,7 @@ public class ChatActivity extends AppCompatActivity implements FirebaseAuth.Auth
private static final String TAG = "RecyclerViewDemo";

private FirebaseAuth mAuth;
private DatabaseReference mChatIndicesRef;
private DatabaseReference mChatRef;
private Button mSendButton;
private EditText mMessageEdit;
Expand All @@ -69,7 +63,9 @@ protected void onCreate(Bundle savedInstanceState) {
mSendButton = (Button) findViewById(R.id.sendButton);
mMessageEdit = (EditText) findViewById(R.id.messageEdit);

mChatRef = FirebaseDatabase.getInstance().getReference().child("chats");
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
mChatIndicesRef = ref.child("chatIndices");
mChatRef = ref.child("chats");

mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
Expand All @@ -78,11 +74,13 @@ public void onClick(View v) {
String name = "User " + uid.substring(0, 6);

Chat chat = new Chat(name, mMessageEdit.getText().toString(), uid);
mChatRef.push().setValue(chat, new DatabaseReference.CompletionListener() {
DatabaseReference chatRef = mChatRef.push();
mChatIndicesRef.child(chatRef.getKey()).setValue(true);
chatRef.setValue(chat, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference reference) {
if (databaseError != null) {
Log.e(TAG, "Failed to write message", databaseError.toException());
public void onComplete(DatabaseError error, DatabaseReference reference) {
if (error != null) {
Log.e(TAG, "Failed to write message", error.toException());
}
}
});
Expand All @@ -92,11 +90,7 @@ public void onComplete(DatabaseError databaseError, DatabaseReference reference)
});

mMessages = (RecyclerView) findViewById(R.id.messagesList);

mManager = new LinearLayoutManager(this);
mManager.setReverseLayout(false);

mMessages.setHasFixedSize(false);
mMessages.setLayoutManager(mManager);
}

Expand All @@ -107,10 +101,10 @@ public void onStart() {
// Default Database rules do not allow unauthenticated reads, so we need to
// sign in before attaching the RecyclerView adapter otherwise the Adapter will
// not be able to read any data from the Database.
if (!isSignedIn()) {
signInAnonymously();
} else {
if (isSignedIn()) {
attachRecyclerViewAdapter();
} else {
signInAnonymously();
}
}

Expand All @@ -137,28 +131,34 @@ public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {

private void attachRecyclerViewAdapter() {
Query lastFifty = mChatRef.limitToLast(50);
mRecyclerViewAdapter = new FirebaseRecyclerAdapter<Chat, ChatHolder>(
Chat.class, R.layout.message, ChatHolder.class, lastFifty) {

@Override
public void populateViewHolder(ChatHolder chatView, Chat chat, int position) {
chatView.setName(chat.getName());
chatView.setText(chat.getMessage());
mRecyclerViewAdapter =
new FirebaseIndexRecyclerAdapter<Chat, ChatHolder>(
Copy link
Collaborator Author

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.

Chat.class,
R.layout.message,
ChatHolder.class,
mChatIndicesRef,
lastFifty) {
@Override
public void populateViewHolder(ChatHolder chatView, Chat chat, int position) {
chatView.setName(chat.getName());
chatView.setText(chat.getMessage());

FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser != null && chat.getUid().equals(currentUser.getUid())) {
chatView.setIsSender(true);
} else {
chatView.setIsSender(false);
}
}
};
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser != null && chat.getUid().equals(currentUser.getUid())) {
chatView.setIsSender(true);
} else {
chatView.setIsSender(false);
}
}
};

// Scroll to bottom on new messages
mRecyclerViewAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
mManager.smoothScrollToPosition(mMessages, null, mRecyclerViewAdapter.getItemCount());
mManager.smoothScrollToPosition(mMessages,
null,
mRecyclerViewAdapter.getItemCount());
}
});

Expand All @@ -168,17 +168,25 @@ public void onItemRangeInserted(int positionStart, int itemCount) {
private void signInAnonymously() {
Toast.makeText(this, "Signing in...", Toast.LENGTH_SHORT).show();
mAuth.signInAnonymously()
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
.addOnSuccessListener(this, new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult result) {
attachRecyclerViewAdapter();
}
})
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
Copy link
Collaborator Author

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.

@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d(TAG, "signInAnonymously:onComplete:" + task.isSuccessful());
if (task.isSuccessful()) {
Toast.makeText(ChatActivity.this, "Signed In",
Toast.LENGTH_SHORT).show();
attachRecyclerViewAdapter();
Toast.makeText(getApplicationContext(),
R.string.signed_in,
Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(ChatActivity.this, "Sign In Failed",
Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(),
R.string.sign_in_failed,
Toast.LENGTH_SHORT)
.show();
}
}
});
Expand All @@ -193,96 +201,4 @@ public void updateUI() {
mSendButton.setEnabled(isSignedIn());
mMessageEdit.setEnabled(isSignedIn());
}

public static class Chat {
private String mName;
private String mMessage;
private String mUid;

public Chat() {
// Needed for Firebase
}

public Chat(String name, String message, String uid) {
mName = name;
mMessage = message;
mUid = uid;
}

public String getName() {
return mName;
}

public void setName(String name) {
mName = name;
}

public String getMessage() {
return mMessage;
}

public void setMessage(String message) {
mMessage = message;
}

public String getUid() {
return mUid;
}

public void setUid(String uid) {
mUid = uid;
}
}

public static class ChatHolder extends RecyclerView.ViewHolder {
private final TextView mNameField;
private final TextView mTextField;
private final FrameLayout mLeftArrow;
private final FrameLayout mRightArrow;
private final RelativeLayout mMessageContainer;
private final LinearLayout mMessage;
private final int mGreen300;
private final int mGray300;

public ChatHolder(View itemView) {
super(itemView);
mNameField = (TextView) itemView.findViewById(R.id.name_text);
mTextField = (TextView) itemView.findViewById(R.id.message_text);
mLeftArrow = (FrameLayout) itemView.findViewById(R.id.left_arrow);
mRightArrow = (FrameLayout) itemView.findViewById(R.id.right_arrow);
mMessageContainer = (RelativeLayout) itemView.findViewById(R.id.message_container);
mMessage = (LinearLayout) itemView.findViewById(R.id.message);
mGreen300 = ContextCompat.getColor(itemView.getContext(), R.color.material_green_300);
mGray300 = ContextCompat.getColor(itemView.getContext(), R.color.material_gray_300);
}

public void setIsSender(boolean isSender) {
final int color;
if (isSender) {
color = mGreen300;
mLeftArrow.setVisibility(View.GONE);
mRightArrow.setVisibility(View.VISIBLE);
mMessageContainer.setGravity(Gravity.END);
} else {
color = mGray300;
mLeftArrow.setVisibility(View.VISIBLE);
mRightArrow.setVisibility(View.GONE);
mMessageContainer.setGravity(Gravity.START);
}

((GradientDrawable) mMessage.getBackground()).setColor(color);
((RotateDrawable) mLeftArrow.getBackground()).getDrawable()
.setColorFilter(color, PorterDuff.Mode.SRC);
((RotateDrawable) mRightArrow.getBackground()).getDrawable()
.setColorFilter(color, PorterDuff.Mode.SRC);
}

public void setName(String name) {
mNameField.setText(name);
}

public void setText(String text) {
mTextField.setText(text);
}
}
}
67 changes: 67 additions & 0 deletions app/src/main/java/com/firebase/uidemo/database/ChatHolder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.firebase.uidemo.database;

import android.graphics.PorterDuff;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.RotateDrawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.firebase.uidemo.R;

public class ChatHolder extends RecyclerView.ViewHolder {
private final TextView mNameField;
private final TextView mTextField;
private final FrameLayout mLeftArrow;
private final FrameLayout mRightArrow;
private final RelativeLayout mMessageContainer;
private final LinearLayout mMessage;
private final int mGreen300;
private final int mGray300;

public ChatHolder(View itemView) {
super(itemView);
mNameField = (TextView) itemView.findViewById(R.id.name_text);
mTextField = (TextView) itemView.findViewById(R.id.message_text);
mLeftArrow = (FrameLayout) itemView.findViewById(R.id.left_arrow);
mRightArrow = (FrameLayout) itemView.findViewById(R.id.right_arrow);
mMessageContainer = (RelativeLayout) itemView.findViewById(R.id.message_container);
mMessage = (LinearLayout) itemView.findViewById(R.id.message);
mGreen300 = ContextCompat.getColor(itemView.getContext(), R.color.material_green_300);
mGray300 = ContextCompat.getColor(itemView.getContext(), R.color.material_gray_300);
}

public void setIsSender(boolean isSender) {
final int color;
if (isSender) {
color = mGreen300;
mLeftArrow.setVisibility(View.GONE);
mRightArrow.setVisibility(View.VISIBLE);
mMessageContainer.setGravity(Gravity.END);
} else {
color = mGray300;
mLeftArrow.setVisibility(View.VISIBLE);
mRightArrow.setVisibility(View.GONE);
mMessageContainer.setGravity(Gravity.START);
}

((GradientDrawable) mMessage.getBackground()).setColor(color);
((RotateDrawable) mLeftArrow.getBackground()).getDrawable()
.setColorFilter(color, PorterDuff.Mode.SRC);
((RotateDrawable) mRightArrow.getBackground()).getDrawable()
.setColorFilter(color, PorterDuff.Mode.SRC);
}

public void setName(String name) {
mNameField.setText(name);
}

public void setText(String text) {
mTextField.setText(text);
}
}
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
<string name="no_internet_connection">No internet connection</string>
<string name="signed_in_header">You are signed in!</string>
<string name="sign_out">Sign out</string>
<string name="signed_in">Signed In</string>
<string name="sign_in_failed">Sign In Failed</string>
<string name="delete_account_label">Delete account</string>
<string name="sign_out_failed">Sign out failed</string>
<string name="delete_account_failed">Delete account failed</string>
Expand Down
Loading