Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm building a chat application that sends messages and media files, my problem is that when a user sends a message or a media file it displays twice. But when I close my chat activity and open it again it displays as expected i.e. once.
My Chat Activity
public class ChatActivityy extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
mAuth = FirebaseAuth.getInstance();
messageSenderID = mAuth.getCurrentUser().getUid();
Rootref = FirebaseDatabase.getInstance().getReference();
UsersRef = FirebaseDatabase.getInstance().getReference("Users");
messageReceiverID = getIntent().getExtras().get("visit_user_id").toString();
messageReceiverName = getIntent().getExtras().get("visit_user_name").toString();
//Toast.makeText(this, messageReceiverID, Toast.LENGTH_SHORT).show();
//Toast.makeText(this, messageReceiverName, Toast.LENGTH_SHORT).show();
InitializeControllers();
DisplayLastSeen();
GetUserInfo();
userName.setText(messageReceiverName);
SendMessageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
notify = true;
SendMessage();
//MessageInputText.setText("");
}
});
SendFilesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CharSequence[] options = new CharSequence[]
{
"Images",
"Videos",
"Documents",
"Audio",
"Cancel"
};
AlertDialog.Builder builder = new AlertDialog.Builder(ChatActivityy.this);
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int i) {
if (i == 0)
{
checker = "image";
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent.createChooser(intent, "Select Image"), 438);
}
}
});
builder.show();
}
});
apiService = Client.getClient("https://fcm.googleapis.com/").create(APIService.class);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 438 && resultCode == RESULT_OK && data != null & data.getData() !=null)
{
loadingBar.setTitle("Sending file");
loadingBar.setMessage("Please wait, your file is sending");
loadingBar.setCanceledOnTouchOutside(false);
loadingBar.show();
fileUri = data.getData();
if(checker.equals("image"))
{
StorageReference storageReference = FirebaseStorage.getInstance().getReference().child("Image Files");
String messageSenderRef = "Messages/" + messageSenderID + "/" + messageReceiverID;
String messageReceiverRef = "Messages/" + messageReceiverID + "/" + messageSenderID;
DatabaseReference userMessageKeyRef = Rootref.child("Messages")
.child(messageSenderID).child(messageReceiverID).push();
final String messagePushID = userMessageKeyRef.getKey();
final StorageReference filepath = storageReference.child(messagePushID + "." + "jpg");
uploadTask = filepath.putFile(fileUri);
uploadTask.continueWithTask(new Continuation() {
#Override
public Object then(#NonNull Task task) throws Exception {
if (!task.isSuccessful())
{
throw task.getException();
}
return filepath.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful())
{
Uri downloadUrl = task.getResult();
myUrl = downloadUrl.toString();
Map messageTextBody = new HashMap();
messageTextBody.put("message", myUrl);
messageTextBody.put("name", fileUri.getLastPathSegment());
messageTextBody.put("type", checker);
messageTextBody.put("from", messageSenderID);
messageTextBody.put("to", messageReceiverID);
messageTextBody.put("messageID", messagePushID);
messageTextBody.put("time", saveCurrentTime);
messageTextBody.put("date", saveCurrentDate);
Map messageBodyDetails = new HashMap();
messageBodyDetails.put(messageSenderRef + "/" + messagePushID, messageTextBody);
messageBodyDetails.put(messageReceiverRef + "/" + messagePushID, messageTextBody);
Rootref.updateChildren(messageBodyDetails).addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if (task.isSuccessful()) {
loadingBar.dismiss();
// Toast.makeText(ChatActivityy.this, "Message Sent", Toast.LENGTH_SHORT).show();
} else {
loadingBar.dismiss();
Toast.makeText(ChatActivityy.this, "Message not sent", Toast.LENGTH_SHORT).show();
}
MessageInputText.setText("");
}
});
}
}
});
}
else
{
loadingBar.dismiss();
Toast.makeText(this, "No Image Selected", Toast.LENGTH_SHORT).show();
}
}
}
#Override
protected void onStart() {
super.onStart();
Rootref.child("Messages").child(messageSenderID).child(messageReceiverID)
.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Messages messages = dataSnapshot.getValue(Messages.class);
messagesList.add(messages);
messageAdapter.notifyDataSetChanged();
userMessagesList.smoothScrollToPosition(userMessagesList.getAdapter().getItemCount());
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void SendMessage()
{
String messageText = MessageInputText.getText().toString();
if (TextUtils.isEmpty(messageText))
{
Toast.makeText(this, "Enter a Message", Toast.LENGTH_SHORT).show();
}
else {
String messageSenderRef = "Messages/" + messageSenderID + "/" + messageReceiverID;
String messageReceiverRef = "Messages/" + messageReceiverID + "/" + messageSenderID;
DatabaseReference userMessageKeyRef = Rootref.child("Messages")
.child(messageSenderID).child(messageReceiverID).push();
String messagePushID = userMessageKeyRef.getKey();
Map messageTextBody = new HashMap();
messageTextBody.put("message", messageText);
messageTextBody.put("type", "text");
messageTextBody.put("from", messageSenderID);
messageTextBody.put("to", messageReceiverID);
messageTextBody.put("messageID", messagePushID);
messageTextBody.put("time", saveCurrentTime);
messageTextBody.put("date", saveCurrentDate);
Map messageBodyDetails = new HashMap();
messageBodyDetails.put(messageSenderRef + "/" + messagePushID, messageTextBody);
messageBodyDetails.put(messageReceiverRef + "/" + messagePushID, messageTextBody);
Rootref.updateChildren(messageBodyDetails).addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if (task.isSuccessful()) {
// Toast.makeText(ChatActivityy.this, "Message Sent", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ChatActivityy.this, "Message not sent", Toast.LENGTH_SHORT).show();
}
MessageInputText.setText("");
}
});
final String msg = messageText;
// UsersRef.child(messageSenderID);
UsersRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Friends user = dataSnapshot.getValue(Friends.class);
if (notify) {
sendNotification(messageReceiverID, user.getName(), msg);
}
notify = false;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
My Adapter
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageViewHolder>
{
private List<Messages> userMessagesList;
private FirebaseAuth mAuth;
private DatabaseReference usersRef;
MessageAdapter(List<Messages> userMessagesList) {
this.userMessagesList = userMessagesList;
}
class MessageViewHolder extends RecyclerView.ViewHolder
{
TextView senderMessageText, receiverMessageText;
ZoomageView senderImage, receiverImage;
ImageView senderMedia, receiverMedia;
public MessageViewHolder(#NonNull View itemView) {
super(itemView);
senderMessageText = (TextView) itemView.findViewById(R.id.sender_message_text);
receiverMessageText = (TextView) itemView.findViewById(R.id.receiver_message_text);
}
}
#NonNull
#Override
public MessageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_messages_layout, parent, false);
mAuth = FirebaseAuth.getInstance();
return new MessageViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final MessageViewHolder messageViewHolder, final int position) {
String messageSenderID = mAuth.getCurrentUser().getUid();
final Messages messages = userMessagesList.get(position);
String fromUserID = messages.getFrom();
String fromMessageType = messages.getType();
usersRef = FirebaseDatabase.getInstance().getReference().child("Users").child(fromUserID);
messageViewHolder.receiverMessageText.setVisibility(View.GONE);
messageViewHolder.senderMessageText.setVisibility(View.GONE);
if (fromMessageType.equals("text")) {
if (fromUserID.equals(messageSenderID)) {
messageViewHolder.senderMessageText.setVisibility(View.VISIBLE);
messageViewHolder.senderMessageText.setBackgroundResource(R.drawable.sender_message);
messageViewHolder.senderMessageText.setTextColor(Color.BLACK);
messageViewHolder.senderMessageText.setText(messages.getMessage() + "\n \n" + messages.getTime() + " - " + messages.getDate());
} else {
messageViewHolder.receiverMessageText.setVisibility(View.VISIBLE);
messageViewHolder.receiverMessageText.setBackgroundResource(R.drawable.receiver_messages_layout);
messageViewHolder.receiverMessageText.setTextColor(Color.BLACK);
messageViewHolder.receiverMessageText.setText(messages.getMessage() + "\n \n" + messages.getTime() + " - " + messages.getDate());
}
}
if (fromUserID.equals(messageSenderID))
{
messageViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (userMessagesList.get(position).getType().equals("text"))
{
CharSequence[] options = new CharSequence[]
{
"Delete for me",
"Delete for Everyone",
"Copy",
"Cancel"
};
AlertDialog.Builder builder = new AlertDialog.Builder(messageViewHolder.itemView.getContext());
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int i) {
if (i == 0)
{
deleteSentMessage(position, messageViewHolder);
}
else if (i == 1)
{
deleteMessageForEveryone(position, messageViewHolder);
}
else if (i == 2)
{
ClipboardManager myClipboard = (ClipboardManager) v.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData myClip = ClipData.newPlainText("label", messageViewHolder.senderMessageText.getText().toString());
myClipboard.setPrimaryClip(myClip);
Toast.makeText(v.getContext(), "Copied to clipboard" , Toast.LENGTH_SHORT ).show();
//setClipboard(mContext, messageViewHolder.senderMessageText.toString());
}
}
});
builder.show();
}
}
#Override
public int getItemCount() {
return userMessagesList.size();
}
}
This might be because you attach a listener in onStart. After you start a new intent, the activity is paused, and then, after the user has added a new message and resumed the old activity, method onStart is called one more time. So at that moment you have two listeners. If the next added message is duplicated three times, then it must be the actual problem. Try moving EventListener to onCreate. Or check if it is already assigned to your directory (Idk if this is possible with the database), if you want to leave it in onStart
Related
I have successfully uploaded the media in the firebase but i'm unable to retrieve it. apparently it shows that the media_problem is pointing to a null object. below is my code.
This is my code to retrieve:
this.view.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(Dash_agri.this.getApplicationContext(), "TOO FAST! TRY AGAIN", Toast.LENGTH_LONG);
try {
Dash_agri.this.firestore.collection("problems").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
public void onComplete( Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
Dash_agri.this.records.clear();
Iterator it = ((QuerySnapshot) task.getResult()).iterator();
while (it.hasNext()) {
QueryDocumentSnapshot document = (QueryDocumentSnapshot) it.next();
Dash_agri.this.single_ID = document.getId();
Dash_agri.this.single_name = (String) document.get("NAME_problems");
Dash_agri.this.single_phone = (String) document.get("PHONE_problems");
Dash_agri.this.single_description = (String) document.get("DESCRIPTION_problems");
Dash_agri.this.single_URL = (String) document.get("MEDIA_problems");
String view_media = "Touch to view media";
new SpannableString(view_media).setSpan(new ClickableSpan() {
public void onClick(View widget) {
Toast.makeText(Dash_agri.this.getApplicationContext(), "inside", Toast.LENGTH_LONG).show();
}
}, 0, 9, 33);
Dash_agri.this.record_id.add(Dash_agri.this.single_ID);
ArrayList<String> arrayList = Dash_agri.this.records;
StringBuilder sb = new StringBuilder();
sb.append("QUERY#");
sb.append(Dash_agri.this.single_ID);
sb.append(" by ");
sb.append(Dash_agri.this.single_name);
sb.append("\n");
sb.append(Dash_agri.this.single_description);
sb.append("\n\n");
sb.append(view_media);
arrayList.add(sb.toString());
}
}
}
});
} catch (Exception e) {
Toast.makeText(Dash_agri.this.getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG);
}
Dash_agri.this.listView.setAdapter(new ArrayAdapter<>(Dash_agri.this.getApplicationContext(), R.layout.simple_list_item_1, Dash_agri.this.records));
}
});
This is my code to upload:
public class Upload extends AppCompatActivity {
private static final int PICK_MEDIA_REQUEST = 1;
String MEDIA_url;
String NAME;
String PHONE;
long TIME_ID = System.currentTimeMillis();
String USER_ID;
TextView file;
FirebaseAuth firebaseAuth;
FirebaseFirestore firestore;
Button img;
EditText prob;
ProgressBar progressBar;
StorageReference storageReference;
Button upld;
/* access modifiers changed from: private */
public Uri uri;
Button vid;
/* access modifiers changed from: protected */
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1 && resultCode == -1 && data != null && data.getData() != null) {
this.uri = data.getData();
this.file.setText(this.uri.getPath());
}
}
/* access modifiers changed from: protected */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView((int) R.layout.activity_upload);
this.firebaseAuth = FirebaseAuth.getInstance();
this.firestore = FirebaseFirestore.getInstance();
this.storageReference = FirebaseStorage.getInstance().getReference();
this.prob = (EditText) findViewById(R.id.editTextProblem_upload);
this.file = (TextView) findViewById(R.id.textViewFile_upload);
this.img = (Button) findViewById(R.id.buttonImage_upload);
this.vid = (Button) findViewById(R.id.buttonVideo_Upload);
this.upld = (Button) findViewById(R.id.buttonUpload_upload);
this.progressBar = (ProgressBar) findViewById(R.id.progressBar_upload);
this.progressBar.setVisibility(View.VISIBLE);
this.img.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction("android.intent.action.GET_CONTENT");
Upload.this.startActivityForResult(intent, 1);
}
});
this.vid.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction("android.intent.action.GET_CONTENT");
startActivityForResult(intent, 1);
}
});
try {
this.upld.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (prob.getText().toString().isEmpty() || file.getText().toString().equals("No file selected")) {
Toast.makeText(getApplicationContext(), "Please write your problem and upload a file!", Toast.LENGTH_SHORT).show();
return;
}
progressBar.setVisibility(View.VISIBLE);
upload_file_also(uri);
USER_ID = firebaseAuth.getCurrentUser().getUid();
TIME_ID = System.currentTimeMillis();
firestore.collection("users").document(USER_ID).addSnapshotListener(new EventListener<DocumentSnapshot>() {
public void onEvent(#javax.annotation.Nullable DocumentSnapshot documentSnapshot, #javax.annotation.Nullable FirebaseFirestoreException e) {
NAME = documentSnapshot.getString("NAME_");
PHONE = documentSnapshot.getString("PHONE_");
}
});
NAME = NAME == null ? "null" : NAME;
PHONE = PHONE == null ? "null" : PHONE;
if (!NAME.equals("null") && !PHONE.equals("null")) {
CollectionReference collection = firestore.collection("problems");
StringBuilder sb = new StringBuilder();
sb.append("ProbID-");
sb.append(TIME_ID);
DocumentReference documentReference = collection.document(String.valueOf(sb.toString()));
Map<String, Object> user_problems = new HashMap<>();
user_problems.put("DESCRIPTION_problems", prob.getText().toString());
user_problems.put("NAME_problems", NAME);
user_problems.put("PHONE_problems", PHONE);
user_problems.put("MEDIA_problems", Upload.this.MEDIA_url);
documentReference.set(user_problems).addOnSuccessListener(new OnSuccessListener<Void>() {
public void onSuccess(Void aVoid) {
Toast.makeText(Upload.this.getApplicationContext(), "Successfully uploaded", Toast.LENGTH_SHORT).show();
Upload.this.startActivity(new Intent(Upload.this.getApplicationContext(), Dash_farmer.class));
Upload.this.finish();
}
});
}
}
});
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
/* access modifiers changed from: private */
public void upload_file_also(Uri fileUri) {
StorageReference storageReference2 = this.storageReference;
StringBuilder sb = new StringBuilder();
sb.append("ProbID-");
sb.append(this.TIME_ID);
final StorageReference sr = storageReference2.child(String.valueOf(sb.toString()));
sr.putFile(fileUri).addOnSuccessListener((OnSuccessListener<TaskSnapshot>) new OnSuccessListener<TaskSnapshot>() {
public void onSuccess(TaskSnapshot taskSnapshot) {
sr.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
public void onSuccess(Uri uri) {
Upload.this.MEDIA_url = uri.toString();
Upload.this.progressBar.setVisibility(View.VISIBLE);
Upload.this.upld.setText("TAP AGAIN TO UPLOAD MEDIA");
}
});
}
});
}
}
I'm unable to find why this isn't working. Please put a light on where this is going wrong.
I am trying to create a chat. However, I am facing a big issue. When I delete an entry from the chat recyclerView, the entry stays there, but is removed from the firebase db as expected (I mean only removing from db is working). It only disapears when I close the activity and open it again. My recyclerView has a feature of load 10 more entries each time a user scrolls.
I dont understand how can I remove the entry from the recyclerView?
I need to call the function loadMoreMessages()? Refresh the activity?
MessageAdapter.java
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageViewHolder>{
public class MessageViewHolder extends RecyclerView.ViewHolder {
public TextView messageText, displayName;
public CircleImageView profileImage;
public ImageView messageImage;
public MessageViewHolder(View itemView) {
super(itemView);
messageText = (TextView) itemView.findViewById(R.id.message_text_layout);
profileImage = (CircleImageView) itemView.findViewById(R.id.message_profile_layout);
displayName = (TextView) itemView.findViewById(R.id.name_text_layout);
messageImage = (ImageView) itemView.findViewById(R.id.message_image_layout);
}
}
private List<Messages> mMessageList;
private FirebaseAuth mAuth;
private DatabaseReference mUserDatabase;
private DatabaseReference mUserDatabaseSettings;
private String rul, fromUser_t;
private UserAccountSettings mUserAccountSettings;
public MessageAdapter(List<Messages> mMessageList) {
this.mMessageList = mMessageList;
}
#Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_single_layout,parent,false);
mAuth = FirebaseAuth.getInstance();
return new MessageViewHolder(v);
}
#Override
public void onBindViewHolder(final MessageViewHolder holder, final int position) {
final String current_user_id = mAuth.getCurrentUser().getUid();
final Messages c = mMessageList.get(position);
final String from_user = c.getFrom();
final String message_type = c.getType();
final String messageContent = c.getMessage();
/**
* popup for text message
*/
// check if the message is from the current user
if(from_user.equals(current_user_id))
{
holder.messageText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//popup menu to select option
CharSequence options[] = new CharSequence[]
{
"Delete from my phone",
"Delete for Everyone" ,
"Cancel"
};
final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
builder.setTitle("Message Options");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Click Event for each item.
if(i == 0)
{
deleteSentMessage(position, holder);
// Intent intent = new Intent(holder.itemView.getContext(), ChatActivity.class);
// holder.itemView.getContext().startActivity(intent);
//MessageViewHolder.class.notify();
holder.messageText.setPaintFlags(holder.messageText.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
else if(i == 1)
{
deleteMessageForEveryOne(position, holder);
// Intent intent = new Intent(holder.itemView.getContext(), ChatActivity.class);
// holder.itemView.getContext().startActivity(intent);
//notifyDataSetChanged();
//holder.messageText.setVisibility(View.GONE);
}
}
});
builder.show();
}
});
}else
{
// similar code to check if the message is from the other user
}
holder.messageText.setVisibility(View.GONE);
holder.messageImage.setVisibility(View.GONE);
if("text".equals(message_type))
{
holder.messageText.setVisibility(View.VISIBLE);
if(from_user.equals(current_user_id))
{
holder.messageText.setBackgroundResource(R.drawable.message_text_background);
holder.messageText.setTextColor(Color.WHITE);
//todo left right not working
holder.messageText.setGravity(Gravity.LEFT);
}else
{
holder.messageText.setBackgroundColor(Color.WHITE);
holder.messageText.setTextColor(Color.BLACK);
holder.messageText.setGravity(Gravity.RIGHT);
}
holder.messageText.setText(c.getMessage());
}else
{
holder.messageImage.setVisibility(View.VISIBLE);
UniversalImageLoader.setImage(messageContent,holder.messageImage,null,"");
}
}
#Override
public int getItemCount() {
return mMessageList.size();
}
/**
function to Delete from my phone
**/
private void deleteSentMessage(final int position, final MessageViewHolder holder)
{
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("messages")
.child(mMessageList.get(position).getFrom())
.child(mMessageList.get(position).getTo())
.child(mMessageList.get(position).getMessageID())
.removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task)
{
if(task.isSuccessful())
{
Toast.makeText(holder.itemView.getContext(), "Deleted Successfully.", Toast.LENGTH_SHORT).show();
}else
{
Toast.makeText(holder.itemView.getContext(), "Error Occurred.", Toast.LENGTH_SHORT).show();
}
}
});
}
/**
function to Delete from receiver phone
**/
private void deleteReceiveMessage(final int position, final MessageViewHolder holder)
{
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("messages")
.child(mMessageList.get(position).getTo())
.child(mMessageList.get(position).getFrom())
.child(mMessageList.get(position).getMessageID())
.removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task)
{
if(task.isSuccessful())
{
Toast.makeText(holder.itemView.getContext(), "Deleted Successfully.", Toast.LENGTH_SHORT).show();
}else
{
Toast.makeText(holder.itemView.getContext(), "Error Occurred.", Toast.LENGTH_SHORT).show();
}
}
});
}
/**
function to Delete from both sides
**/
private void deleteMessageForEveryOne(final int position, final MessageViewHolder holder)
{
final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("messages")
.child(mMessageList.get(position).getTo())
.child(mMessageList.get(position).getFrom())
.child(mMessageList.get(position).getMessageID())
.removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task)
{
if(task.isSuccessful())
{
rootRef.child("messages")
.child(mMessageList.get(position).getFrom())
.child(mMessageList.get(position).getTo())
.child(mMessageList.get(position).getMessageID())
.removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful())
{
Toast.makeText(holder.itemView.getContext(), "Deleted Successfully.", Toast.LENGTH_SHORT).show();
}
}
});
}else
{
Toast.makeText(holder.itemView.getContext(), "Error Occurred.", Toast.LENGTH_SHORT).show();
}
}
});
}
}
ChatActivity.java
public class ChatActivity extends AppCompatActivity {
private static final String TAG = "ChatActivity";
//todo check is user is logedin
//user with whom Iam talking to
private String mChatUser;
private Toolbar mChatToolbar;
private DatabaseReference mRootRef;
private TextView mTitleView, mLastSeenView;
private CircleImageView mProfileImage;
private FirebaseAuth mAuth;
private String mCurrentUserId;
private ImageButton mChatAddBtn;
private ImageButton mChatSendBtn;
private EditText mChatMessageView;
private RecyclerView mMessagesList;
private SwipeRefreshLayout mRefreshLayout;
private final List<Messages> messagesList = new ArrayList<>();
private LinearLayoutManager mLinearLayout;
private MessageAdapter mAdapter;
private static final int TOTAL_ITEMS_TO_LOAD = 10;
private int mCurrentPage = 1;
private int itemPos =0;
private String mLastKey = "";
private String mPrevKey = "";
private static final int GALLERY_PICK = 1;
//Storage Firebase
private StorageReference mImageStorage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
// create a toolbar and set the title as the user with we are chatting to
mChatToolbar = (Toolbar) findViewById(R.id.chat_app_bar);
setSupportActionBar(mChatToolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
// to add a custom view to the toolbar
actionBar.setDisplayShowCustomEnabled(true);
mRootRef = FirebaseDatabase.getInstance().getReference();
mAuth = FirebaseAuth.getInstance();
mCurrentUserId = mAuth.getCurrentUser().getUid();
mChatUser = getIntent().getStringExtra("user_id");
String userName = getIntent().getStringExtra("user_name");
getSupportActionBar().setTitle(userName);
// String userName = getIntent().getStringExtra("user_name");
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View action_bar_view = inflater.inflate(R.layout.chat_custom_bar, null);
actionBar.setCustomView(action_bar_view);
// ---------- Custom Action bar items ---
mTitleView = (TextView) findViewById(R.id.custom_bar_title);
mLastSeenView = (TextView) findViewById(R.id.custom_bar_seen);
mProfileImage = (CircleImageView) findViewById(R.id.custom_bar_image);
mChatAddBtn = (ImageButton) findViewById(R.id.chat_add_btn);
mChatSendBtn = (ImageButton) findViewById(R.id.chat_send_btn);
mChatMessageView = (EditText) findViewById(R.id.chat_message_view);
mAdapter = new MessageAdapter(messagesList);
mImageStorage= FirebaseStorage.getInstance().getReference();
mMessagesList = (RecyclerView) findViewById(R.id.messages_list);
mRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.message_swipe_layout);
mLinearLayout = new LinearLayoutManager(this);
mMessagesList.setHasFixedSize(true);
mMessagesList.setLayoutManager(mLinearLayout);
//mMessagesList.setItemViewCacheSize(25);
mMessagesList.setDrawingCacheEnabled(true);
mMessagesList.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
mMessagesList.setAdapter(mAdapter);
loadMessages();
mTitleView.setText(userName);
mRootRef.child("users").child(mChatUser).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String online = dataSnapshot.child("lastSeen").getValue().toString();
//String image = dataSnapshot.child()
if(online.equals("true")){
mLastSeenView.setText("Online");
}else {
GetTimeAgo getTimeAgo = new GetTimeAgo();
long lastTime = Long.parseLong(online);
String lastSeenTime = getTimeAgo.getTimeAgo(lastTime, getApplicationContext());
mLastSeenView.setText(lastSeenTime);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
mRootRef.child("Chat").child(mCurrentUserId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(!dataSnapshot.hasChild(mChatUser)){
Map chatAddMap = new HashMap();
chatAddMap.put("seen", false);
chatAddMap.put("timestamp", ServerValue.TIMESTAMP);
Map chatUserMap = new HashMap();
chatUserMap.put("Chat/" + mCurrentUserId + "/" + mChatUser, chatAddMap); //add map to current user
chatUserMap.put("Chat/" + mChatUser + "/" + mCurrentUserId, chatAddMap);
mRootRef.updateChildren(chatUserMap, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(#Nullable DatabaseError databaseError, #NonNull DatabaseReference databaseReference) {
if(databaseError != null){
//Log.d(TAG, "onComplete: CHAT LOG", databaseError.getMessage());
Log.e(TAG, "onComplete: CHAT_LOG" + databaseError.getMessage().toString());
}
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
mChatSendBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendMessage();
}
});
// open gallery to get an image
mChatAddBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(galleryIntent,"SELECT IMAGE"), GALLERY_PICK);
}
});
//pagination
mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mCurrentPage++;
// each time it loads a new page should go to position zero
itemPos = 0;
loadMoreMessages();
}
});
}
/**
* load more messages everytime uesr refreshes
*/
private void loadMoreMessages() {
DatabaseReference messageRef = mRootRef.child("messages").child(mCurrentUserId).child(mChatUser);
Query messageQuery = messageRef.orderByKey().endAt(mLastKey).limitToLast(10);
messageQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Messages message = dataSnapshot.getValue(Messages.class);
String messageKey = dataSnapshot.getKey();
if(!mPrevKey.equals(messageKey)){
messagesList.add(itemPos++, message);
Log.d(TAG, "onChildAdded: xx" + mPrevKey + "---" + mLastKey);
} else {
mPrevKey = mLastKey;
}
if(itemPos == 1){
mLastKey = messageKey;
}
Log.d(TAG, "onChildAdded: TOTALKEUS" + "lastkey: " + mLastKey + " | Prev key : " + mPrevKey + " | Message Key : " + messageKey);
mAdapter.notifyDataSetChanged();
mRefreshLayout.setRefreshing(false);
mLinearLayout.scrollToPositionWithOffset(itemPos , 0);
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
/**
* method used to load messages once
*/
private void loadMessages() {
//query to get pagination and last 10 messages
DatabaseReference messageRef = mRootRef.child("messages").child(mCurrentUserId).child(mChatUser);
Query messageQuery = messageRef.limitToLast(mCurrentPage * TOTAL_ITEMS_TO_LOAD);
messageQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Messages message = dataSnapshot.getValue(Messages.class);
itemPos++;
if(itemPos == 1){
// get the key to be user as a start point when loading more items
String messageKey = dataSnapshot.getKey();
mLastKey = messageKey;
mPrevKey = messageKey;
Log.d(TAG, "onChildAdded: last " +mLastKey + " prev " + mPrevKey + " messa " + messageKey + "-----------");
}
messagesList.add(message);
mAdapter.notifyDataSetChanged();
//pagination - define the bottom of the recycler view
//automatic scroll to bottom
mMessagesList.scrollToPosition(messagesList.size() - 1);
mRefreshLayout.setRefreshing(false);
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
/**
* send photo message
* #param requestCode
* #param resultCode
* #param data
*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == GALLERY_PICK && resultCode == RESULT_OK){
Uri imageUri = data.getData();
final String current_user_ref = "messages/" + mCurrentUserId + "/" + mChatUser;
final String chat_user_ref = "messages/" + mChatUser + "/" + mCurrentUserId;
DatabaseReference user_message_push = mRootRef.child("messages")
.child(mCurrentUserId).child(mChatUser).push();
final String push_id = user_message_push.getKey();
StorageReference filepath = mImageStorage.child("message_images").child( push_id + ".jpg");
filepath.putFile(imageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if(task.isSuccessful()){
Task<Uri> result = task.getResult().getMetadata().getReference().getDownloadUrl();
result.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String download_url = uri.toString();
Map messageMap = new HashMap();
messageMap.put("message", download_url);
messageMap.put("seen", false);
messageMap.put("type", "image");
messageMap.put("time", ServerValue.TIMESTAMP);
messageMap.put("from", mCurrentUserId);
messageMap.put("to", mChatUser);
messageMap.put("messageID", push_id );
Map messageUserMap = new HashMap();
messageUserMap.put(current_user_ref + "/" + push_id, messageMap);
messageUserMap.put(chat_user_ref + "/" + push_id, messageMap);
mChatMessageView.setText("");
mRootRef.updateChildren(messageUserMap, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if(databaseError != null){
Log.d("CHAT_LOG", databaseError.getMessage().toString());
}
}
});
}
});
}
}
});
}
}
}
``
You're using a ChildEventListener in your messageQuery, which has these main methods:
onChildAdded, which is called initially for every child node matching your messageQuery query, and subsequently when any child node is added to the database that falls into messageQuery.
onChildRemoved, which is called when any child node (that falls) is removed from the database (or at least to the part that messageQuery is listening to).
onChildChanged, which is called when any child node that messageQuery is listening is modified in the database.
If I look at your implementation, you've only implemented onChildAdded. So when you remove a child node from the database, Firebase tells your ChildEventListener about it, but that then does nothing.
To remove the message from the UI when it gets removed from the database, you will need to implement:
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
// TODO: remove the message matching dataSnapshot from messagesList
// TODO: call adapter.notifyDataSetChanged() so that the UI gets updates
}
The list changes size so you have to give new list size to your logic.
Thanks Frank and Vedprakash. It was a quit obvious. At that time I did not understand how to pass the position and remove the item using onChildRemoved. Now I understand. What I did was based on this post: How to use onChildRemoved in Firebase Realtime Database?
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
Toast.makeText(ChatActivity.this, "Entered on this part!", Toast.LENGTH_SHORT).show();
int index = keyList.indexOf(dataSnapshot.getKey());
messagesList.remove(index);
keyList.remove(index);
//mAdapter.notifyDataSetChanged();
mAdapter.notifyItemRemoved(index);
}
I tested it and is working fine. However, It has a little issue. My chat loads 10 items (defined by: private static final int TOTAL_ITEMS_TO_LOAD = 10;). If the user scrolls it will load more items.
When I open the chat page, the items loaded are from "2" to "11" But, when I delete item, for example, "9" the item "1" show up. Meaning that, the item right before the position zero of the messagesList will show up.
I tried several things. My last try was set the mLinearLayout.scrollToPosition, decrease the TOTAL_ITEMS_TO_LOAD. And the issue stays alive. :(
Before delete
After delete item
I am making an chat app and I want to do the following:
When starting the MainActivity, check if the user is logged in. If not, start FirebaseAuthUI.
But FirebaseAuth only supports a few parameters and, to add more, I created a Database node do each user, which store other parameters.
To get this parameters, after finishing FirebaseAuth, the user is redirected to an Activity that get all extra information and store in the user's node in the Database. All of this is working just fine.
But after the user fill the information in this Info Activity and finish the register, it should go back to MainActivity and stay there. How can I do that?
I am trying it this way:
I added to each user a Boolean variable called userCompleted, which informs if the user have already gave their information. I check if this variable is false, and if so, I call the Info Activity intent and, in the when the user press the button to complete the registration in this Activity, it sets the userCompleted value to true in the user node in the Database and then start an intent that leads to MainActivity.
The problem is that in the Database, userCompleted is set to true and then immediately goes back to false, and I don't know why. Also, I guess I am having trouble on reading userCompleted from the Database, probably because I haven't worked much with asynchronous tasks.
I used a variable isUserCompleted declared in Main Activity to get track of the userCompleted value.
A way to check if is the first time the user is logging in would be useful too, although it wouldn't solve my whole problem.
This is my current code:
(if need more to try to understand the problem just ask in the comments)
Create AuthStateListener
public void setAuthStateListener(){
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
onSignInInitialize(user);
Log.d(TAG, "userUid = " + user.getUid());
Toast.makeText(SearchActivity.this, "Signed in!", Toast.LENGTH_SHORT).show();
} else {
onSignOutCleanup();
startLoginUI();
}
}
};
}
onSignInInitialize()
public void onSignInInitialize(final FirebaseUser user){
mLoggedFBUser = user;
mUserReference = mUsersDatabaseReference.child(user.getUid());
mUserReference.child("uid").setValue(user.getUid());
mUserReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
isUserCompleted = user.isUserCompleted();
Log.d(TAG, "UserCompleted (onDataChanged) "+ isUserCompleted);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Log.d(TAG, "UserCompleted (Before startActivity if) "+ isUserCompleted);
if (!isUserCompleted) {
startCreateProfileActivity(user);
}
Log.d(TAG, "UserCompleted (After startActivity if) "+ isUserCompleted);
mUserReference.child("username").setValue(user.getDisplayName());
mUserReference.child("email").setValue(user.getEmail());
attachChildEventListener();
}
Go back to Main Activity
mFinishButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mUserDatabaseReference.child("userCompleted").setValue(true);
Intent intent = new Intent (CreateVolunteerProfile.this, SearchActivity.class);
startActivity(intent);
}
});
Entire MainActivity block (Actually it's called SearchActivity)
public class SearchActivity extends AppCompatActivity implements RecyclerAdapter.UserItemClickListener {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private ArrayList<User> users = new ArrayList<User>();
private String mLoggedUserId = "user2";
private String mLoggedUsername;
private User mLoggedUser;
private FirebaseUser mLoggedFBUser;
//private boolean isUserCompleted;
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mPreferencesEditor;
private boolean firstTime = true;
private static final String TAG = "Search Activity";
private static final int USER_CLICK = 1;
private static final int RC_SIGN_IN = 1;
private static final int RC_CREATE_PROFILE = 2;
//Firebase
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference mUsersDatabaseReference;
private DatabaseReference mUserReference;
private ChildEventListener mChildEventListener;
private FirebaseAuth mFirebaseAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
View loadingView = findViewById(R.id.cl_loading);
loadingView.setVisibility(View.VISIBLE);
//RecyclerView
recyclerView = findViewById(R.id.rv_users);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new RecyclerAdapter(users, this);
recyclerView.setAdapter(adapter);
//Firebase
mFirebaseDatabase = FirebaseDatabase.getInstance();
mFirebaseAuth = FirebaseAuth.getInstance();
mUsersDatabaseReference = mFirebaseDatabase.getReference().child("users");
setAuthStateListener();
loadingView.setVisibility(View.GONE);
}
#Override
protected void onResume() {
super.onResume();
mFirebaseAuth.addAuthStateListener(mAuthStateListener);
}
#Override
protected void onPause() {
super.onPause();
if (mAuthStateListener != null)
mFirebaseAuth.removeAuthStateListener(mAuthStateListener);
detachChildEventListener();
clearAdapter();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
Log.wtf(TAG, "onSaveInstanceState userId = "+ mLoggedUserId);
//Log.wtf(TAG, "UserCompleted (onSaveInstanceState) " + isUserCompleted);
outState.putString("userId", mLoggedUserId);
//outState.putBoolean("isUserCompleted", isUserCompleted);
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mLoggedUserId = savedInstanceState.getString("userId");
//isUserCompleted = savedInstanceState.getBoolean("isUserCompleted");
//Log.wtf(TAG, "UserCompleted (onRestoreInstanceState) " + isUserCompleted);
Log.wtf(TAG, "onRestoreInstanceState userId = "+ mLoggedUserId);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if((requestCode == RC_SIGN_IN) && firstTime){
if (resultCode == RESULT_OK){
//Toast.makeText(this, "Signed in!", Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED){
Toast.makeText(this, "Sign in canceled!", Toast.LENGTH_SHORT).show();
finish();
}
}
if((requestCode == RC_CREATE_PROFILE)){
if (resultCode == RESULT_OK){
//isUserCompleted = true;
}
}
}
#Override
public void onUserItemClick(int clickedUserIndex) {
Intent intent = new Intent (this, ChatActivity.class);
FirebaseUser user = mFirebaseAuth.getCurrentUser();
if(user != null) {
mLoggedUserId = user.getUid();
intent.putExtra("user1", mLoggedUserId);
String mUserRecieverId = users.get(clickedUserIndex).getUid();
intent.putExtra("user2", mUserRecieverId);
Log.wtf(TAG, "SearchActivity // user = " + users.get(clickedUserIndex));
Log.wtf("1", "SearchActivity // mLoggedUserId = " + mLoggedUserId + " // users.getUid() = " + users.get(clickedUserIndex).getUid());
startActivityForResult(intent, USER_CLICK);
}
else {
Toast.makeText(this, "ERROR", Toast.LENGTH_SHORT).show();
}
}
public void setAuthStateListener(){
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
mUserReference = mUsersDatabaseReference.child(user.getUid());
onSignInInitialize(user);
Log.wtf(TAG, "userUid = " + user.getUid());
Toast.makeText(SearchActivity.this, "Signed in!", Toast.LENGTH_SHORT).show();
} else {
onSignOutCleanup();
startLoginUI();
}
}
};
}
public void onSignInInitialize(final FirebaseUser user){
mLoggedFBUser = user;
mUserReference = mUsersDatabaseReference.child(user.getUid());
mUserReference.child("uid").setValue(user.getUid());
boolean isUserCompleted = false;
mUserReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
isUserCompleted = user.isUserCompleted();
Log.wtf(TAG, "UserCompleted (onDataChanged) "+ isUserCompleted);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Log.wtf(TAG, "UserCompleted (Before startActivity if) "+ isUserCompleted);
if (!isUserCompleted) {
startCreateProfileActivity(user);
}
Log.wtf(TAG, "UserCompleted (After startActivity if) "+ isUserCompleted);
mUserReference.child("username").setValue(user.getDisplayName());
mUserReference.child("email").setValue(user.getEmail());
attachChildEventListener();
}
public void onSignOutCleanup(){
mLoggedUser = null;
mLoggedUserId = null;
mLoggedUsername = null;
detachChildEventListener();
clearAdapter();
}
public void attachChildEventListener(){
if (mChildEventListener == null){
mChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
User user = dataSnapshot.getValue(User.class);
users.add(user);
Log.d(TAG, "onChildAdded userId = "+ user.getUid());
//adapter.notifyItemInserted(users.size()-1);
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) { }
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) { }
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) { }
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }
};
}
mUsersDatabaseReference.addChildEventListener(mChildEventListener);
}
public void detachChildEventListener(){
if (mChildEventListener != null){
mUsersDatabaseReference.removeEventListener(mChildEventListener);
mChildEventListener = null;
}
}
public void clearAdapter() {
final int size = users.size();
if (size > 0) {
for (int i = 0; i < size; i++) {
users.remove(0);
}
adapter.notifyItemRangeRemoved(0, size);
}
}
public void startCreateProfileActivity(FirebaseUser user){
mUsersDatabaseReference.child(user.getUid()).child("userCompleted").setValue(false);
Intent intent = new Intent(SearchActivity.this, CreateProfileActivity.class);
intent.putExtra("userId", user.getUid());
startActivityForResult(intent, RC_CREATE_PROFILE);
}
public void startLoginUI(){
startActivityForResult(
AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(false)
.setLogo(R.mipmap.logo)
.setAvailableProviders(Arrays.asList(
new AuthUI.IdpConfig.GoogleBuilder().build(),
//new AuthUI.IdpConfig.FacebookBuilder().build(),
//new AuthUI.IdpConfig.TwitterBuilder().build(),
//new AuthUI.IdpConfig.GitHubBuilder().build(),
new AuthUI.IdpConfig.EmailBuilder().build()))
//new AuthUI.IdpConfig.PhoneBuilder().build(),
//new AuthUI.IdpConfig.AnonymousBuilder().build()))
.build(),
RC_SIGN_IN);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.search_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.sign_out_item:
AuthUI.getInstance().signOut(this);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
I think the simplest way is if a user clicked on finish Btn successfully make a flag with true else make it false
in your MainActivity
firebase.auth().onAuthStateChanged(function(user) {
// User signed in and not registered
if (user&&!isPressedOnFinishBtn) {
// User is signed in.
}
user clicked on finish btn
else if(isPressedOnFinishBtn) {
// No user is signed in.
}
});
This is how you can do that .
Create a method inside your Login activity .
private void AllowUserToLogin() {
String userName = userEmail.getText().toString();
String userPass = userPassword.getText().toString();
if (TextUtils.isEmpty(userName) || TextUtils.isEmpty(userPass)) {
Toast.makeText(this, "Enter user Name / password first . . .", Toast.LENGTH_SHORT).show();
} else {
dialogBar.setTitle("Sign In ");
dialogBar.setMessage("Please Wait . . .");
dialogBar.setCanceledOnTouchOutside(true);
dialogBar.show();
mAuth.signInWithEmailAndPassword(userName, userPass)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
String currentUserID = mAuth.getCurrentUser().getUid();
String deviceToken = Settings.Secure.getString(getApplicationContext().getContentResolver(),
Settings.Secure.ANDROID_ID);
UsersRef.child(currentUserID).child("device_token")
.setValue(deviceToken)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
sendUserToMainActivity();
Toast.makeText(LoginPage.this, "Logged in Successfull . . . ", Toast.LENGTH_SHORT).show();
dialogBar.dismiss();
}
}
});
} else {
String error = task.getException().toString();
Toast.makeText(LoginPage.this, "Wrong Email or Password: " + error, Toast.LENGTH_SHORT).show();
dialogBar.dismiss();
}
}
});
}
}
and on ur onClick() method .
#Override
public void onClick(View v) {
if (v == needNewAccount) {
sendUserToRegisterActivity();
} else if (v == loginButton) {
AllowUserToLogin();
}else if(v == phone_button){
Intent phoneLoginIntent = new Intent(LoginPage.this , PhoneLoginActivity.class);
startActivity(phoneLoginIntent);
}
}
this is sendUserToRegisterActivity()
private void sendUserToRegisterActivity() {
Intent registerIntent = new Intent(LoginPage.this, RegisterationForm.class);
startActivity(registerIntent);
}
This is sendUserToMainActivity() .
private void sendUserToMainActivity() {
Intent mainIntent = new Intent(LoginPage.this, MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(mainIntent);
finish();
}
I am trying to run my app using Adapters and I am getting this error while doing that:
Mentioning that there are 3 adapters: ReviewsAdapter, StandupWithKey and VideoAdapter.
05-07 20:16:57.707 5326-5326/com.example.sefi.authenticationproject E/ReviewsAdapter: onBindViewHolder() >> 0
05-07 20:16:57.708 5326-5326/com.example.sefi.authenticationproject E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sefi.authenticationproject, PID: 5326
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.sefi.authenticationproject.adapter.ReviewsAdapter.onBindViewHolder(ReviewsAdapter.java:48)
at com.example.sefi.authenticationproject.adapter.ReviewsAdapter.onBindViewHolder(ReviewsAdapter.java:18)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6482)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6515)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5458)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5724)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5563)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5559)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2229)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1556)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1516)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:608)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3693)
at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3109)
at android.view.View.measure(View.java:19734)
at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1210)
at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:1550)
at android.view.View.measure(View.java:19734)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:19734)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
at android.view.View.measure(View.java:19734)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6120)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:687)
at android.view.View.measure(View.java:19734)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2271)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1358)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1607)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1246)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6301)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
And this are my files:
ReviewsAdapter.java
public class ReviewsAdapter extends RecyclerView.Adapter<ReviewsAdapter.ReviewViewHolder> {
private final String TAG = "ReviewsAdapter";
private List<Review> reviewsList;
public ReviewsAdapter(List<Review> reviewsList) {
this.reviewsList = reviewsList;
}
#Override
public ReviewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.e(TAG,"onCreateViewHolder() >>");
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.activity_standup_details, parent, false);
Log.e(TAG,"onCreateViewHolder() <<");
return new ReviewViewHolder(parent.getContext(),itemView);
}
#Override
public void onBindViewHolder(ReviewViewHolder holder, int position) {
Log.e(TAG,"onBindViewHolder() >> " + position);
Review review = reviewsList.get(position);
holder.getUserMail().setText(review.getUserEmail());
holder.getUserReview().setText(review.getUserReview());
holder.getUserRating().setRating(review.getUserRating());
Log.e(TAG,"onBindViewHolder() << "+ position);
}
#Override
public int getItemCount() {
return reviewsList.size();
}
public class ReviewViewHolder extends RecyclerView.ViewHolder {
private TextView userReview;
private TextView userMail;
private RatingBar userRating;
public ReviewViewHolder(Context context, View view) {
super(view);
userReview = (TextView) view.findViewById(R.id.user_review);
userMail = (TextView) view.findViewById(R.id.user_mail);
userRating = (RatingBar) view.findViewById(R.id.user_rating);
}
public TextView getUserReview() {
return userReview;
}
public void setUserReview(TextView userReview) {
this.userReview = userReview;
}
public TextView getUserMail() {
return userMail;
}
public void setUserMail(TextView userMail) {
this.userMail = userMail;
}
public RatingBar getUserRating() {
return userRating;
}
public void setUserRating(RatingBar userRating) {
this.userRating = userRating;
}
}
}
StandupDetails.java
public class StandupDetails extends Activity {
public final String TAG = "StandupDetails";
private Standup standup;
private String key;
private User user;
private FloatingActionButton writeReview;
private Button buyPlay;
private MediaPlayer mediaPlayer;
private RecyclerView recyclerViewStandupReviews;
private DatabaseReference standupReviewsRef;
private List<Review> reviewsList = new ArrayList<>();
private boolean standupWasPurchased;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_standup_details);
key = getIntent().getStringExtra("key");
standup = getIntent().getParcelableExtra("standup");
user = getIntent().getParcelableExtra("user");
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
StorageReference thumbRef = FirebaseStorage
.getInstance()
.getReference()
.child("thumbs/" + standup.getThumbImage());
// Load the image using Glide
thumbRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Glide.with(StandupDetails.this).load(uri)
.into((ImageView)findViewById(R.id.imageViewSong));
}
});
((TextView) findViewById(R.id.textViewName)).setText(standup.getName());
buyPlay = ((Button) findViewById(R.id.buttonBuyPlay));
buyPlay.setText("BUY $" + standup.getPrice());
Iterator i = user.getMyStandups().iterator();
while (i.hasNext()) {
if (i.next().equals(key)) {
standupWasPurchased = true;
buyPlay.setText("PLAY");
break;
}
}
buyPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.e(TAG, "buyPlay.onClick() >> file=" + standup.getName());
FirebaseUser fbUser = FirebaseAuth.getInstance().getCurrentUser();
String info = fbUser.getProviderId();
if (standupWasPurchased) {
Log.e(TAG, "buyPlay.onClick() >> Playing purchased standup");
//User purchased the standup so he can play it
playCurrentStandup(standup.getFile());
}
else{
Log.e(TAG, "buyPlay.onClick() >> Purchase the standup");
user.getMyStandups().add(key);
user.upgdateTotalPurchase(standup.getPrice());
DatabaseReference userRef = FirebaseDatabase.getInstance().getReference("Users");
userRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(user);
standupWasPurchased = true;
buyPlay.setText("PLAY");
}
Log.e(TAG, "playStandup.onClick() <<");
}
});
writeReview = (FloatingActionButton) findViewById(R.id.buttonNewReview);
writeReview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.e(TAG, "writeReview.onClick() >>");
Intent intent = new Intent(getApplicationContext(),ReviewActivity.class);
intent.putExtra("standup", standup);
intent.putExtra("key", key);
intent.putExtra("user",user);
startActivity(intent);
finish();
Log.e(TAG, "writeReview.onClick() <<");
}
});
recyclerViewStandupReviews = findViewById(R.id.standup_reviews);
recyclerViewStandupReviews.setHasFixedSize(true);
recyclerViewStandupReviews.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerViewStandupReviews.setItemAnimator(new DefaultItemAnimator());
ReviewsAdapter reviewsAdapter = new ReviewsAdapter(reviewsList);
recyclerViewStandupReviews.setAdapter(reviewsAdapter);
standupReviewsRef = FirebaseDatabase.getInstance().getReference("Standup/" + key +"/reviews");
standupReviewsRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.e(TAG, "onDataChange() >> Standup/" + key);
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Review review = dataSnapshot.getValue(Review.class);
reviewsList.add(review);
}
recyclerViewStandupReviews.getAdapter().notifyDataSetChanged();
Log.e(TAG, "onDataChange(Review) <<");
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "onCancelled(Review) >>" + databaseError.getMessage());
}
});
Log.e(TAG, "onCreate() <<");
}
#Override
protected void onPause() {
super.onPause();
stopPlayingCurrentStandup();
}
private void playCurrentStandup(String standupFile) {
Log.e(TAG, "playCurrentStandup() >> standupFile=" + standupFile);
if (stopPlayingCurrentStandup()) {
Log.e(TAG, "playCurrentStandup() << Stop playing current Standup");
return;
}
FirebaseStorage.getInstance()
.getReference("StandupsFile/" + standupFile)
.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri downloadUrl) {
Log.e(TAG, "onSuccess() >> " + downloadUrl.toString());
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(downloadUrl.toString()));
intent.setDataAndType(Uri.parse(downloadUrl.toString()), "video/mp4");
startActivity(intent);
//mediaPlayer.setDataSource(downloadUrl.toString());
//mediaPlayer.prepare(); // might take long! (for buffering, etc)
//mediaPlayer.start();
} catch (Exception e) {
Log.w(TAG, "playStandup() error:" + e.getMessage());
}
Log.e(TAG, "onSuccess() <<");
}
});
Log.e(TAG, "playCurrentStandup() << ");
}
private boolean stopPlayingCurrentStandup() {
if (mediaPlayer.isPlaying()) {
Log.e(TAG, "onSuccess() >> Stop the media player");
//Stop the media player
mediaPlayer.stop();
mediaPlayer.reset();
buyPlay.setText("PLAY");
return true;
}
return false;
}
}
ReviewActivity
public class ReviewActivity extends AppCompatActivity {
private final String TAG = "ReviewActivity";
private Standup standup;
private String key;
private User user;
private int prevRating = -1;
private TextView userReview;
private RatingBar userRating;
private DatabaseReference standupRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.e(TAG, "onCreate() >>");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_review);
key = getIntent().getStringExtra("key");
standup = getIntent().getParcelableExtra("standup");
user = getIntent().getParcelableExtra("user");
userReview = findViewById(R.id.new_user_review);
userRating = findViewById(R.id.new_user_rating);
standupRef = FirebaseDatabase.getInstance().getReference("Standup/" + key);
standupRef.child("/reviews/" + FirebaseAuth.getInstance().getCurrentUser().getUid()).
addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.e(TAG, "onDataChange(Review) >> " + snapshot.getKey());
Review review = snapshot.getValue(Review.class);
if (review != null) {
userReview.setText(review.getUserReview());
userRating.setRating(review.getUserRating());
prevRating = review.getUserRating();
}
Log.e(TAG, "onDataChange(Review) <<");
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "onCancelled(Review) >>" + databaseError.getMessage());
}
});
Log.e(TAG, "onCreate() <<");
}
public void onSubmitClick(View v) {
Log.e(TAG, "onSubmitClick() >>");
standupRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Log.e(TAG, "doTransaction() >>" );
Standup standup = mutableData.getValue(Standup.class);
if (standup == null ) {
Log.e(TAG, "doTransaction() << standup is null" );
return Transaction.success(mutableData);
}
if (prevRating == -1) {
// Increment the review count and rating only in case the user enters a new review
standup.incrementReviewCount();
standup.incrementRating((int)userRating.getRating());
} else{
standup.incrementRating((int)userRating.getRating() - prevRating);
}
mutableData.setValue(standup);
Log.e(TAG, "doTransaction() << standup was set");
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {
Log.e(TAG, "onComplete() >>" );
if (databaseError != null) {
Log.e(TAG, "onComplete() << Error:" + databaseError.getMessage());
return;
}
if (committed) {
Review review = new Review(
userReview.getText().toString(),
(int)userRating.getRating(),
user.getEmail());
standupRef.child("/reviews/" + FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(review);
}
Intent intent = new Intent(getApplicationContext(),StandupDetails.class);
intent.putExtra("standup", standup);
intent.putExtra("key", key);
intent.putExtra("user",user);
startActivity(intent);
finish();
Log.e(TAG, "onComplete() <<" );
}
});
Log.e(TAG, "onSubmitClick() <<");
}
}
StandupPlayerMain.java
public class StandupPlayerMain extends Activity {
private final String TAG = "StandUp Player Tag";
private DatabaseReference allStandupRef;
private DatabaseReference myUserRef;
private List<StandupWithKey> standupList = new ArrayList<>();
private GoogleSignInClient mGoogleSignInClient;
private RecyclerView recyclerView;
private VideoAdapter standupAdapter;
private User myUser;
private FirebaseAuth mAuth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_standup_player_main);
Log.e(TAG, "onCreate() >>");
mAuth= FirebaseAuth.getInstance();
recyclerView = (RecyclerView) findViewById(R.id.standups_list);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
FirebaseUser fbUser = FirebaseAuth.getInstance().getCurrentUser();
if (fbUser != null) {
myUserRef = FirebaseDatabase.getInstance().getReference("Users/" + fbUser.getUid());
myUserRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.e(TAG, "onDataChange(User) >> " + snapshot.getKey());
myUser = snapshot.getValue(User.class);
getAllStandups();
Log.e(TAG, "onDataChange(User) <<");
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "onCancelled(Users) >>" + databaseError.getMessage());
}
});
Log.e(TAG, "onCreate() <<");
} else {
getAllStandups();
}
}
private void getAllStandups() {
Log.e(TAG,"GET ALL STANDUPS >>");
standupList.clear();
standupAdapter = new VideoAdapter(standupList,myUser);
recyclerView.setAdapter(standupAdapter);
//getAllSongsUsingValueListenrs();
getAllVideoUsingChildListenrs();
Log.e(TAG,"GET ALL STANDUPS <<");
}
private void getAllVideoUsingChildListenrs() {
allStandupRef = FirebaseDatabase.getInstance().getReference("Standup");
allStandupRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.e(TAG, "onDataChange(Standup) >> " + snapshot.getKey());
updateStandupList(snapshot);
Log.e(TAG, "onDataChange(Standup) <<");
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "onCancelled(Songs) >>" + databaseError.getMessage());
}
});
}
private void getAllSongsUsingChildListenrs() {
allStandupRef = FirebaseDatabase.getInstance().getReference("Standup");
allStandupRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot snapshot, String previousChildName){
Log.e(TAG, "onChildAdded(Standup) >> " + snapshot.getKey());
StandupWithKey standupwithKey = new StandupWithKey(snapshot.getKey(),snapshot.getValue(Standup.class));
standupList.add(standupwithKey);
recyclerView.getAdapter().notifyDataSetChanged();
Log.e(TAG, "onChildAdded(Standup) <<");
}
#Override
public void onChildChanged(DataSnapshot snapshot, String previousChildName){
Log.e(TAG, "onChildChanged(Standup) >> " + snapshot.getKey());
Standup standup = snapshot.getValue(Standup.class);
String key = snapshot.getKey();
for (int i = 0 ; i < standupList.size() ; i++) {
StandupWithKey standupWithKey = (StandupWithKey) standupList.get(i);
if (standupWithKey.getKey().equals(snapshot.getKey())) {
standupWithKey.setStandup(standup);
recyclerView.getAdapter().notifyDataSetChanged();
break;
}
}
Log.e(TAG, "onChildChanged(Standup) <<");
}
#Override
public void onChildMoved(DataSnapshot snapshot, String previousChildName){
Log.e(TAG, "onChildMoved(Standup) >> " + snapshot.getKey());
Log.e(TAG, "onChildMoved(Standup) << Doing nothing");
}
#Override
public void onChildRemoved(DataSnapshot snapshot){
Log.e(TAG, "onChildRemoved(Standup) >> " + snapshot.getKey());
Standup standup =snapshot.getValue(Standup.class);
String key = snapshot.getKey();
for (int i = 0 ; i < standupList.size() ; i++) {
StandupWithKey standupwithKey = (StandupWithKey) standupList.get(i);
if (standupwithKey.getKey().equals(snapshot.getKey())) {
standupList.remove(i);
recyclerView.getAdapter().notifyDataSetChanged();
Log.e(TAG, "onChildRemoved(Standup) >> i="+i);
break;
}
}
Log.e(TAG, "onChildRemoved(Standup) <<");
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "onCancelled(Standup) >>" + databaseError.getMessage());
}
});
}
private void updateStandupList(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Standup standup = dataSnapshot.getValue(Standup.class);
Log.e(TAG, "updateStandupList() >> adding standup: " + standup.getName());
String key = dataSnapshot.getKey();
standupList.add(new StandupWithKey(key,standup));
}
recyclerView.getAdapter().notifyDataSetChanged();
}
public void onSignOutClick(View V) {
Log.e(TAG, "onSignOutClick() >>");
logOutFromGoogleAccount();
LoginManager.getInstance().logOut();
mAuth.signOut();
Intent intent = new Intent(StandupPlayerMain.this,LogInActivity.class);
startActivity(intent);
Log.e(TAG, "onSignOutClick() <<");
}
private void logOutFromGoogleAccount()
{
Log.e(TAG, "logOutFromGoogleAccount() >>");
GoogleSignInOptions gso = new GoogleSignInOptions
.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestProfile()
.requestEmail()
.build();
// Build a GoogleSignInClient with the options specified by gso.
mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
mGoogleSignInClient.signOut();
Log.e(TAG, "logOutFromGoogleAccount() <<");
}
public void onSearchButtonClick(View v) {
String searchString = ((EditText)findViewById(R.id.edit_text_search_standup)).getText().toString();
String orderBy = ((RadioButton)findViewById(R.id.radioButtonByReviews)).isChecked() ? "reviewsCount" : "price";
Query searchStandup;
Log.e(TAG, "onSearchButtonClick() >> searchString="+searchString+ ",orderBy="+orderBy);
standupList.clear();
if (searchString != null && !searchString.isEmpty()) {
searchStandup = allStandupRef.orderByChild("name").startAt(searchString).endAt(searchString + "\uf8ff");
} else {
searchStandup = allStandupRef.orderByChild(orderBy);
}
searchStandup.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.e(TAG, "onDataChange(Query) >> " + snapshot.getKey());
updateStandupList(snapshot);
Log.e(TAG, "onDataChange(Query) <<");
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "onCancelled() >>" + databaseError.getMessage());
}
});
Log.e(TAG, "onSearchButtonClick() <<");
}
public void onRadioButtonCLick(View v) {
switch (v.getId()) {
case R.id.radioButtonByPrice:
((RadioButton)findViewById(R.id.radioButtonByReviews)).setChecked(false);
break;
case R.id.radioButtonByReviews:
((RadioButton)findViewById(R.id.radioButtonByPrice)).setChecked(false);
break;
}
}
}
You're using the same layout for the StandupDetails activity and the recycler list item:
activity_standup_details.xml
setContentView(R.layout.activity_standup_details);
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.activity_standup_details, parent, false);
You probably want to use different layouts. Because of that your findViewById in the view holder are returning null and that's why you're getting an NPE.
If you're using Butterknife inside your RecyclerAdapter this is the correct way to bind the ViewHolder
public ViewHolder(#NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
If you don't use this it will throw the error.
I have an Activity called ChatActivity where the users are going to be messaging each other. The activity is retrieving the messages as they are sent but when messages are displayed here are's duplicates of every message.
I do have AutoRefresh but it's not refreshing the way I want it to refresh. In my Activity there is swipe refresh as well and when I swipe it refreshes properly. This is the snap when swipe refresh is used:
How can I make my Auto Refresh display my messages like how it does when I swipe to refresh it? here is my code:
public class ChatActivity extends AppCompatActivity {
private Toolbar mChatToolbar; //used
private String mChatUser; //used
private String mthumb_image;
private String userName;
private String mCurrentUserId;
private TextView mUserStatus;
private EditText mChatMessageView;
private CircleImageView mProfileImage;
private FirebaseAuth mAuth;
private ImageButton mChatAddBtn;
private DatabaseReference mRootRef;
// Storage Firebase
private StorageReference mImageStorage;
private static final int GALLERY_PICK = 1;
private RecyclerView mMessagesList;
private SwipeRefreshLayout mRefreshLayout;
private ArrayList<Messages> arrayList_Messages = new ArrayList<>();
private MessageAdapter mAdapter;
private static final int TOTAL_ITEMS_TO_LOAD = 10;
private int mCurrentPage = 1;
private final Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
mChatMessageView = (EditText) findViewById(R.id.chat_message_view);
mChatAddBtn = (ImageButton) findViewById(R.id.chat_add_btn);
mChatToolbar = (Toolbar) findViewById(R.id.chat_app_bar);
setSupportActionBar(mChatToolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowCustomEnabled(true);
//for Custom Action bar
actionBar.setDisplayShowCustomEnabled(true);
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View customBar = inflater.inflate(R.layout.chat_custom_bar,null);
actionBar.setCustomView(customBar);
//getting intent Data
gettingIntentData();
// initializing user view
intCustomBarViewAndSetData();
doTheAutoRefresh();
mRootRef = FirebaseDatabase.getInstance().getReference();
mAuth = FirebaseAuth.getInstance();
mCurrentUserId = mAuth.getCurrentUser().getUid();
//------- IMAGE STORAGE ---------
mImageStorage = FirebaseStorage.getInstance().getReference();
mRootRef.child("Chat").child(mCurrentUserId).child(mChatUser).child("seen").setValue(true);
LoadMessages();
//getting information about user online or offline and thumb image
mRootRef.child("Users").child(mChatUser).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String thumb_image = dataSnapshot.child("thumb_image").getValue().toString();
Picasso.with(ChatActivity.this).load(thumb_image).placeholder(R.drawable.my_profile).into(mProfileImage);
String lastSeen = dataSnapshot.child("online").getValue().toString();
if(lastSeen.equals("true")){
mUserStatus.setText("Online");
}
else{
//converting string into long
Long lastTime = Long.parseLong(lastSeen);
// creating an instance of GetTimeAgo class
GetTimeAgo getTimeAgo = new GetTimeAgo();
String lastSeenTime = GetTimeAgo.getTimeAgo(lastTime,getApplicationContext());
mUserStatus.setText(lastSeenTime);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
//for creating chat object
mRootRef.child("Chat").child(mCurrentUserId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.hasChild(mChatUser)){
Map chatAddMap = new HashMap();
chatAddMap.put("seen",false);
chatAddMap.put("timestamp", ServerValue.TIMESTAMP);
Map chatUserMap = new HashMap();
chatUserMap.put("Chat/"+mCurrentUserId+"/"+mChatUser, chatAddMap);
chatUserMap.put("Chat/"+mChatUser+"/"+mCurrentUserId, chatAddMap);
mRootRef.updateChildren(chatUserMap, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if(databaseError!= null){
Toast.makeText(ChatActivity.this, "Error: "+databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// Retrieving the chat messages into recyclerview
LoadMessages();
mRefreshLayout.setRefreshing(true);
mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mCurrentPage++;
//onRefresh remove the current messages from arraylist and load new messages
arrayList_Messages.clear();
// Load message
LoadMessages();
}
});
}
private void doTheAutoRefresh()
{
handler.postDelayed(new Runnable() {
#Override
public void run()
{
LoadMessages();
// Write code for your refresh logic
doTheAutoRefresh();
}
}, 5000);
}
// Load all messages from database into recyclerView
private void LoadMessages() {
DatabaseReference messageRef = mRootRef.child("messages").child(mCurrentUserId).child(mChatUser);
//Query to load message per page i.e. 10
/*
per page load 10 message and onRefresh mCurrentpage is increment by 1
page 1 => load 10 messages (mCurrentPage = 1 then 1*10 =10)
page 2 => load 20 messages (mCurrentPage = 2 then 2*10 =20) and so on
*/
Query messageQuery = messageRef.limitToLast(mCurrentPage * TOTAL_ITEMS_TO_LOAD);
messageQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Messages messages = dataSnapshot.getValue(Messages.class);
arrayList_Messages.add(messages);
mRefreshLayout.setRefreshing(true);
mAdapter.notifyDataSetChanged();
mMessagesList.scrollToPosition(arrayList_Messages.size()-1);
//when data load completely set refreshing
mRefreshLayout.setRefreshing(false);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
// send button
public void chatSendButton(View view){
sendMessage();
}
//sending a message
private void sendMessage() {
String message = mChatMessageView.getText().toString().trim();
if(!TextUtils.isEmpty(message)){
mChatMessageView.setText("");
String current_user_ref="messages/"+mCurrentUserId+"/"+mChatUser;
String chat_user_ref= "messages/"+mChatUser+"/"+mCurrentUserId;
DatabaseReference chat_push_key = mRootRef.child("messages").child(mCurrentUserId).
child(mChatUser).push();
String push_key = chat_push_key.getKey();
Map messageMap = new HashMap();
messageMap.put("message",message);
messageMap.put("type","text");
messageMap.put("from",mCurrentUserId);
messageMap.put("seen",false);
messageMap.put("time", ServerValue.TIMESTAMP);
Map messageUserMap = new HashMap();
messageUserMap.put(current_user_ref+ "/"+push_key,messageMap);
messageUserMap.put(chat_user_ref+ "/"+push_key,messageMap);
mRootRef.updateChildren(messageUserMap, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if(databaseError!=null){
Log.d("TAG",databaseError.getMessage().toString());
}
}
});
}
}
//add button
public void chatAddButton(View view){
mChatAddBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(galleryIntent, "SELECT IMAGE"), GALLERY_PICK);
}
});
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == GALLERY_PICK && resultCode == RESULT_OK){
Uri imageUri = data.getData();
final String current_user_ref = "messages/" + mCurrentUserId + "/" + mChatUser;
final String chat_user_ref = "messages/" + mChatUser + "/" + mCurrentUserId;
DatabaseReference user_message_push = mRootRef.child("messages")
.child(mCurrentUserId).child(mChatUser).push();
final String push_id = user_message_push.getKey();
StorageReference filepath = mImageStorage.child("message_images").child( push_id + ".jpg");
filepath.putFile(imageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if(task.isSuccessful()){
String download_url = task.getResult().getDownloadUrl().toString();
Map messageMap = new HashMap();
messageMap.put("message", download_url);
messageMap.put("seen", false);
messageMap.put("type", "image");
messageMap.put("time", ServerValue.TIMESTAMP);
messageMap.put("from", mCurrentUserId);
Map messageUserMap = new HashMap();
messageUserMap.put(current_user_ref + "/" + push_id, messageMap);
messageUserMap.put(chat_user_ref + "/" + push_id, messageMap);
mChatMessageView.setText("");
mRootRef.updateChildren(messageUserMap, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if(databaseError != null){
Log.d("CHAT_LOG", databaseError.getMessage().toString());
}
}
});
}
}
});
}
}
private void intCustomBarViewAndSetData() {
TextView mTitleView = (TextView) findViewById(R.id.custom_bar_title);
mUserStatus = (TextView) findViewById(R.id.custom_bar_seen);
mProfileImage = (CircleImageView) findViewById(R.id.custom_bar_image);
mMessagesList = (RecyclerView) findViewById(R.id.messages_list);
mMessagesList.setLayoutManager(new LinearLayoutManager(this));
mRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.message_swipe_layout);
mMessagesList.setHasFixedSize(true);
mAdapter = new MessageAdapter(this, arrayList_Messages);
mMessagesList.setAdapter(mAdapter);
//showing name on toolbar
mTitleView.setText(userName);
mTitleView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent profileIntent = new Intent(ChatActivity.this, ProfileActivity.class);
profileIntent.putExtra("user_id", mChatUser);
startActivity(profileIntent);
}
});
}
private void gettingIntentData() {
Intent intent =getIntent();
userName = intent.getStringExtra("Username");
mChatUser = intent.getStringExtra("user_id");
}
}
Clear the list before load in doTheAutoRefresh().
arrayList_Messages.clear();
LoadMessages();