i am making a simple blog app using firebase as backend. in app i am showing comments list in post detail activity i want to implement edit and delete button in the front of every comment and want to visible it only if that comment write by the current user
this is my postDetailActivity
where should i need to implement the delete button
plz... help me if u need any other info comment....
updated to FirbaseRecyclerView but now delete button not working
public class PostDetailActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "PostDetailActivity";
public static final String EXTRA_POST_KEY = "post_key";
private DatabaseReference mPostReference;
private DatabaseReference mCommentsReference;
private ValueEventListener mPostListener;
protected String mPostKey;
private FirebaseRecyclerAdapter<Comment, CommentViewHolder> mAdapter;
private ImageView postPic;
private TextView mTitleView;
private TextView mBodyView;
private EditText mCommentField;
private Button mCommentButton;
public Button del_comment;
private RecyclerView mCommentsRecycler;
private LinearLayoutManager mlinearLayoutManager;
private String commentKey;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_detail);
// Get post key from intent
mPostKey = getIntent().getStringExtra(EXTRA_POST_KEY);
if (mPostKey == null) {
throw new IllegalArgumentException("Must pass EXTRA_POST_KEY");
}
// Initialize Database
mPostReference = FirebaseDatabase.getInstance().getReference()
.child("posts").child(mPostKey);
mCommentsReference = FirebaseDatabase.getInstance().getReference()
.child("post-comments");
// Initialize Views
// mAuthorView = (TextView) findViewById(R.id.post_author);
mTitleView = (TextView) findViewById(R.id.post_title);
mBodyView = (TextView) findViewById(R.id.post_body);
postPic = (ImageView) findViewById(R.id.form_details_image);
mCommentField = (EditText) findViewById(R.id.field_comment_text);
mCommentButton = (Button) findViewById(R.id.button_post_comment);
del_comment = (Button) findViewById(R.id.remove_comment);
mCommentsRecycler = (RecyclerView) findViewById(R.id.recycler_comments);
mCommentButton.setOnClickListener(this);
mCommentsRecycler.setHasFixedSize(true);
mlinearLayoutManager = new LinearLayoutManager(this);
mCommentsRecycler.setLayoutManager(mlinearLayoutManager);
}
private Query getcommentQuery(DatabaseReference mCommentsReference) {
return mCommentsReference.child(mPostKey);
}
#Override
public void onStart() {
super.onStart();
// Add value event listener to the post
// [START post_value_event_listener]
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
Post post = dataSnapshot.getValue(Post.class);
// [START_EXCLUDE]
// mAuthorView.setText(post.author);
mTitleView.setText(post.title);
mBodyView.setText(post.body);
final String formImage = String.valueOf(post.postDetailPic);
// [END_EXCLUDE]
if (formImage.length() > 0) {
Picasso.with(getApplicationContext()).load(formImage)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(postPic, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
//Try again online if cache failed
Picasso.with(getApplicationContext())
.load(formImage)
//.error(R.drawable.ic_warning_black_24dp)
.into(postPic, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Log.v("Picasso","Could not fetch image");
}
});
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
// [START_EXCLUDE]
Toast.makeText(PostDetailActivity.this, "Failed to load post.",
Toast.LENGTH_SHORT).show();
// [END_EXCLUDE]
}
};
mPostReference.addValueEventListener(postListener);
// [END post_value_event_listener]
// Keep copy of post listener so we can remove it when app stops
mPostListener = postListener;
// Listen for comments
Query commentQuery = getcommentQuery(mCommentsReference);
mAdapter = new FirebaseRecyclerAdapter<Comment, CommentViewHolder>(Comment.class,R.layout.item_comment,
CommentViewHolder.class, commentQuery) {
#Override
protected void populateViewHolder(final CommentViewHolder viewHolder,final Comment model,final int position) {
final DatabaseReference commentRef = getRef(position);
commentKey = commentRef.getKey();
if (model.commenter_id.containsKey(gUid())){
viewHolder.rm_comment.setVisibility(View.VISIBLE);
}
viewHolder.bindToPost(model, new View.OnClickListener() {
#Override
public void onClick(View view) {
mCommentsReference.child(mPostKey).child(commentKey).removeValue();
}
});
}
};
mCommentsRecycler.setAdapter(mAdapter);
}
#Override
public void onStop() {
super.onStop();
// Remove post value event listener
if (mPostListener != null) {
mPostReference.removeEventListener(mPostListener);
}
// Clean up comments listener
mAdapter.cleanup();
}
#Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.button_post_comment) {
postComment();
}
}
private void postComment() {
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
assert mUser != null;
final String uid = mUser.getUid();
final DatabaseReference commentDb = FirebaseDatabase.getInstance().getReference().child("Users").child(uid);
commentDb.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user information
User user = dataSnapshot.getValue(User.class);
String authorName = user.name;
String commentUserPic = user.ProfilePic;
// Create new comment object
String commentText = mCommentField.getText().toString();
HashMap<String, Object> dateCreated;
{
//Otherwise make a new object set to ServerValue.TIMESTAMP
dateCreated = new HashMap<String, Object>();
dateCreated.put("timeStamp", ServerValue.TIMESTAMP);
}
HashMap<String,Boolean> commenter_id ;
{
commenter_id = new HashMap<String, Boolean>();
commenter_id.put(getUid(),true);
}
Comment comment = new Comment(uid, authorName, commentText, commentUserPic, dateCreated, commenter_id);
// Push the comment, it will appear in the list
mCommentsReference.push().setValue(comment);
// Clear the field
mCommentField.setText(null);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
private Context mContext;
private DatabaseReference mDatabaseReference;
private ChildEventListener mChildEventListener;
private List<String> mCommentIds = new ArrayList<>();
private List<Comment> mComments = new ArrayList<>();
private String mkey;
// mContext = context;
// mDatabaseReference = ref;
// Create child event listener
// [START child_event_listener_recycler]
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
taskDeletion(dataSnapshot);
// A new comment has been added, add it to the displayed list
Comment comment = dataSnapshot.getValue(Comment.class);
mkey = dataSnapshot.getKey();
// [START_EXCLUDE]
// Update RecyclerView
mCommentIds.add(dataSnapshot.getKey());
mComments.add(comment);
mAdapter.notifyItemInserted(mComments.size() - 1);
// [END_EXCLUDE]
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
Comment newComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int commentIndex = mCommentIds.indexOf(commentKey);
if (commentIndex > -1) {
// Replace with the new data
mComments.set(commentIndex, newComment);
// Update the RecyclerView
mAdapter.notifyItemChanged(commentIndex);
} else {
Log.w(TAG, "onChildChanged:unknown_child:" + commentKey);
}
// [END_EXCLUDE]
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so remove it.
String commentKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int commentIndex = mCommentIds.indexOf(commentKey);
if (commentIndex > -1) {
// Remove data from the list
mCommentIds.remove(commentIndex);
mComments.remove(commentIndex);
// Update the RecyclerView
mAdapter.notifyItemRemoved(commentIndex);
} else {
Log.w(TAG, "onChildRemoved:unknown_child:" + commentKey);
}
// [END_EXCLUDE]
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
// A comment has changed position, use the key to determine if we are
// displaying this comment and if so move it.
Comment movedComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
// ...
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("PostDetailActivity", "postComments:onCancelled", databaseError.toException());
Toast.makeText(mContext, "Failed to load comments.",
Toast.LENGTH_SHORT).show();
}
};
// ref.addChildEventListener(childEventListener);
// [END child_event_listener_recycler]
// Store reference to listener so it can be removed on app stop
// mChildEventListener = childEventListener;
private String gUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
}
Related
I am showing Firebase data in a RecyclerView and it is working fine.
I have also implemented a SwipeRefreshLayout and when user swipe it, it is getting latest data from Firebase. But whenever I swipe it more than once, it is showing duplicate values although I am clearing the ArrayList and also I am using `swipeRefresh.setEnabled(true)``
Here I am implementing SwipeRefreshLayout:
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
getData();
if (swipeRefresh.isEnabled())
swipeRefresh.setEnabled(false);
}
});
Here is my getData() function:
public void getData() {
pd.setTitle("Loading Data");
pd.setMessage("Please Wait...");
pd.setCancelable(false);
pd.show();
infoList = new ArrayList<>();
distributorList = new ArrayList<>();
infoList.clear();
distributorList.clear();
countChilds = 0;
counter = 0;
final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
final DatabaseReference hotelRef = rootRef.child("Orders");
hotelRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
final String key = String.valueOf(dataSnapshot.getKey());
final String hotelName = String.valueOf(dataSnapshot.child("hotelName").getValue());
final String location = String.valueOf(dataSnapshot.child("location").getValue());
final String quantity = String.valueOf(dataSnapshot.child("quantity").getValue());
final String time = String.valueOf(dataSnapshot.child("time").getValue());
final DatabaseReference progressRef = rootRef.child("Progress").child(key);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
shipment = String.valueOf(dataSnapshot.child("shipment").getValue());
firstMile = String.valueOf(dataSnapshot.child("firstMile").getValue());
distributor = String.valueOf(dataSnapshot.child("distributor").getValue());
}
if (shipment.equals("1") && firstMile.equals("2") && !distributor.equals("2")) {
counter++;
Information information = new Information(key, hotelName, location, quantity, time);
infoList.add(information);
distributorList.add(distributor);
try {
adapter = new DistributorItemAdapter(infoList, distributorList, getContext(), DistributorListFragment.this);
recyclerView.setAdapter(adapter);
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
} catch (NullPointerException e) {
Toast.makeText(getContext(), "No more Orders", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
} else {
shipment = "";
distributor = "";
firstMile = "";
}
if (counter == 0) {
emptyView.setVisibility(View.VISIBLE);
recyclerView.setAdapter(null);
} else
emptyView.setVisibility(View.GONE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("Database Error", databaseError.getMessage());
}
};
progressRef.addListenerForSingleValueEvent(eventListener);
countChilds++;
if (countChilds >= dataSnapshot.getChildrenCount()) {
if (pd.isShowing())
pd.dismiss();
if (!swipeRefresh.isEnabled())
swipeRefresh.setEnabled(true);
swipeRefresh.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) {
}
});
}
You should initialize your adapter where you initialize your recylerview and set adapter to recylcerView like the following.
//recyclerView = findViewById.....
infoList = new ArrayList<>();
distributorList = new ArrayList<>();
adapter = new DistributorItemAdapter(infoList, distributorList, getContext(), DistributorListFragment.this);
recyclerView.setAdapter(adapter);
Now modify your getData() like below.
public void getData() {
pd.setTitle("Loading Data");
pd.setMessage("Please Wait...");
pd.setCancelable(false);
pd.show();
infoList.clear();
distributorList.clear();
countChilds = 0;
counter = 0;
final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
final DatabaseReference hotelRef = rootRef.child("Orders");
hotelRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
final String key = String.valueOf(dataSnapshot.getKey());
final String hotelName = String.valueOf(dataSnapshot.child("hotelName").getValue());
final String location = String.valueOf(dataSnapshot.child("location").getValue());
final String quantity = String.valueOf(dataSnapshot.child("quantity").getValue());
final String time = String.valueOf(dataSnapshot.child("time").getValue());
final DatabaseReference progressRef = rootRef.child("Progress").child(key);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
shipment = String.valueOf(dataSnapshot.child("shipment").getValue());
firstMile = String.valueOf(dataSnapshot.child("firstMile").getValue());
distributor = String.valueOf(dataSnapshot.child("distributor").getValue());
}
if (shipment.equals("1") && firstMile.equals("2") && !distributor.equals("2")) {
counter++;
Information information = new Information(key, hotelName, location, quantity, time);
infoList.add(information);
distributorList.add(distributor);
// notify your adapter that data set is changed
adapter.notifyDatasetChanged();
} else {
shipment = "";
distributor = "";
firstMile = "";
}
if (counter == 0) {
emptyView.setVisibility(View.VISIBLE);
recyclerView.setAdapter(null);
} else
emptyView.setVisibility(View.GONE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("Database Error", databaseError.getMessage());
}
};
progressRef.addListenerForSingleValueEvent(eventListener);
countChilds++;
if (countChilds >= dataSnapshot.getChildrenCount()) {
if (pd.isShowing())
pd.dismiss();
if (!swipeRefresh.isEnabled())
swipeRefresh.setEnabled(true);
swipeRefresh.setRefreshing(false);
}
}
//....
});
}
I don't get the error when i run the app everything works fine, but when i click on the send message button the app crashes but the message still gets sent. below is my code for the chatActivity and logcat message
package com.paddi.paddi.paddi;
public class ChatActivity extends AppCompatActivity
{
private String messageReceiverId;
private String messageReceiverName;
// private Toolbar ChatToolBar;
private TextView userNameTitle;
private TextView userLastSeen;
private CircleImageView userChatProfileImage;
private ImageButton SendMessageButton;
// private ImageButton SelectImageButton;
private EditText InputMessageText;
FirebaseUser fuser;
DatabaseReference rootRef;
private FirebaseAuth mAuth;
private String messageSenderId;
private RecyclerView userMessagesList;
private final List<Messages> messageList = new ArrayList<>();
private LinearLayoutManager linearLayoutManager;
private MessageAdapter messageAdapter;
private static int Gallery_Pick = 1;
private StorageReference MessageImageStorageRef;
private ProgressDialog loadingBar;
private String downloadImageUrl;
Intent intent;
ValueEventListener seenListener;
String userid;
APIServiceFragment apiService;
boolean notify = false;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
rootRef = FirebaseDatabase.getInstance().getReference();
mAuth = FirebaseAuth.getInstance();
messageSenderId = mAuth.getCurrentUser().getUid();
messageReceiverId = getIntent().getExtras().get("visit_user_id").toString();
messageReceiverName = getIntent().getExtras().get("user_name").toString();
MessageImageStorageRef = FirebaseStorage.getInstance().getReference().child("Messages_Pictures");
apiService = Client.getClient("https://fcm.googleapis.com/").create(APIServiceFragment.class);
// ChatToolBar = (Toolbar) findViewById(R.id.chat_bar_layout);
// setSupportActionBar(ChatToolBar);
loadingBar = new ProgressDialog(this);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowCustomEnabled(true);
LayoutInflater layoutInflater = (LayoutInflater)
this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View action_bar_view = layoutInflater.inflate(R.layout.chat_custom_bar, null);
actionBar.setCustomView(action_bar_view);
userNameTitle = (TextView) findViewById(R.id.custom_profile_name);
userLastSeen = (TextView) findViewById(R.id.custom_user_last_seen);
userChatProfileImage = (CircleImageView) findViewById(R.id.custom_profile_image_last_seen);
SendMessageButton = (ImageButton) findViewById(R.id.send_message_btn);
// SelectImageButton = (ImageButton) findViewById(R.id.select_image);
InputMessageText = (EditText) findViewById(R.id.input_message);
messageAdapter = new MessageAdapter(messageList);
userMessagesList = (RecyclerView) findViewById(R.id.messages_list_of_users);
linearLayoutManager = new LinearLayoutManager(this);
userMessagesList.setHasFixedSize(true);
userMessagesList.setLayoutManager(linearLayoutManager);
userMessagesList.setAdapter(messageAdapter);
FetchMessages();
userNameTitle.setText(messageReceiverName);
rootRef.child("Users").child(messageReceiverId).addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
final String online = dataSnapshot.child("online").getValue().toString();
final String userThumb = dataSnapshot.child("user_thumb_image").getValue().toString();
Picasso.with(ChatActivity.this).load(userThumb).fit().centerInside().networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.default_profile)
.into(userChatProfileImage, new Callback() {
#Override
public void onSuccess()
{
}
#Override
public void onError()
{
Picasso.with(ChatActivity.this).load(userThumb).fit().centerInside().placeholder(R.drawable.default_profile).into(userChatProfileImage);
}
});
if (online != null) {
if (online.equals("true"))
{
userLastSeen.setText("online");
}
else
{
LastSeenTime getTime = new LastSeenTime();
long last_seen = Long.parseLong(online);
//problem with last seen time here
String lastSeenDisplayTime = getTime.getTimeAgo(last_seen, getApplicationContext()).toString();
userLastSeen.setText(lastSeenDisplayTime);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError)
{
}
});
SendMessageButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
SendMessage();
}
});
// SelectImageButton.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View v)
// {
// Intent galleryIntent = new Intent();
// galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// galleryIntent.setType("image/*");
// startActivityForResult(galleryIntent, Gallery_Pick);
//}
//});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==Gallery_Pick && resultCode==RESULT_OK &&data!=null)
{
loadingBar.setTitle("Sending Image");
loadingBar.setMessage("Please Wait");
loadingBar.show();
Uri ImageUri = data.getData();
final String message_sender_ref = "Messages/" + messageSenderId + "/" + messageReceiverId;
final String message_receiver_ref = "Messages/" + messageReceiverId + "/" + messageSenderId;
DatabaseReference user_message_key = rootRef.child("Messages").child(messageSenderId)
.child(messageReceiverId).push();
final String message_push_id = user_message_key.getKey();
final StorageReference filePath = MessageImageStorageRef.child(message_push_id + ".jpg");
final StorageTask<UploadTask.TaskSnapshot> taskSnapshotStorageTask = filePath.putFile(ImageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
downloadImageUrl = filePath.getDownloadUrl().toString();
// return filePath.getDownloadUrl();
Map messageTextBody = new HashMap();
messageTextBody.put("message", downloadImageUrl);
messageTextBody.put("isseen", true);
messageTextBody.put("type", "image");
messageTextBody.put("time", ServerValue.TIMESTAMP);
messageTextBody.put("from", messageSenderId);
messageTextBody.put("to", messageReceiverId);
Map messageBodyDetails = new HashMap();
messageBodyDetails.put(message_sender_ref + "/" + message_push_id, messageTextBody);
messageBodyDetails.put(message_receiver_ref + "/" + message_push_id, messageTextBody);
rootRef.updateChildren(messageBodyDetails, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError != null) {
Log.d("Chat_Log", databaseError.getMessage().toString());
}
InputMessageText.setText("");
loadingBar.dismiss();
}
});
Toast.makeText(ChatActivity.this, "Picture Sent Successfully.", Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
} else {
Toast.makeText(ChatActivity.this, "Picture not sent, Try again", Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
}
});
}
}
private void FetchMessages()
{
rootRef.child("Messages").child(messageSenderId).child(messageReceiverId)
.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s)
{
if (dataSnapshot.exists())
{
Messages messages = dataSnapshot.getValue(Messages.class);
messageList.add(messages);
messageAdapter.notifyDataSetChanged();
userMessagesList.smoothScrollToPosition(userMessagesList.getAdapter().getItemCount());
}
}
#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)
{
}
});
// seenMessage(userid);
}
private void seenMessage(final String userid) //add String and userid
{
rootRef = FirebaseDatabase.getInstance().getReference("Messages");
seenListener = rootRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
for (DataSnapshot snapshot : dataSnapshot.getChildren())
{
Messages messages = snapshot.getValue(Messages.class);
if (messages.getTo().equals(fuser.getUid()) && messages.getFrom().equals(ChatActivity.this.userid))//change messages to userid
{
Map messageTextBody = new HashMap();
messageTextBody.put("isseen", true);
snapshot.getRef().updateChildren(messageTextBody);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void SendMessage()
{
notify = true;
String messageText = InputMessageText.getText().toString();
if (TextUtils.isEmpty(messageText))
{
Toast.makeText(ChatActivity.this,
"Input message", Toast.LENGTH_SHORT).show();
}
else
{
String message_sender_ref = "Messages/" + messageSenderId + "/" + messageReceiverId;
final String message_receiver_ref = "Messages/" + messageReceiverId + "/" + messageSenderId;
DatabaseReference user_message_key = rootRef.child("Messages").child(messageSenderId)
.child(messageReceiverId).push();
String message_push_id = user_message_key.getKey();
Map messageTextBody = new HashMap();
messageTextBody.put("message", messageText);
messageTextBody.put("isseen", false);
messageTextBody.put("type", "text");
messageTextBody.put("time", ServerValue.TIMESTAMP);
messageTextBody.put("from", messageSenderId);
messageTextBody.put("to", messageReceiverId);
Map messageBodyDetails = new HashMap();
messageBodyDetails.put(message_sender_ref + "/" + message_push_id, messageTextBody);
messageBodyDetails.put(message_receiver_ref + "/" + message_push_id, messageTextBody);
rootRef.updateChildren(messageBodyDetails).addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task)
{
if (task.isSuccessful())
{
Toast.makeText(ChatActivity.this, "Message Sent", Toast.LENGTH_SHORT).show();
InputMessageText.setText("");
}
else
{
String message = task.getException().getMessage();
Toast.makeText(ChatActivity.this, "Error:" + message, Toast.LENGTH_SHORT).show();
InputMessageText.setText("");
}
}
});
**i tried sending chat notification with the code below
and that was what triggered the error the messages still get sent but the app crashes and restarts itself.**
final String msg = messageText;
rootRef = FirebaseDatabase.getInstance().getReference("Users").child(fuser.getUid());
rootRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
User user = dataSnapshot.getValue(User.class);
if (notify) {
sendNotification(message_receiver_ref, user.getUsername(), msg);
}
notify = false;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
private void sendNotification(String message_receiver_ref, final String username, final String message)
{
DatabaseReference tokens = FirebaseDatabase.getInstance().getReference("Tokens");
Query query = tokens.orderByKey().equalTo(message_receiver_ref);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
for (DataSnapshot snapshot: dataSnapshot.getChildren())
{
Token token = snapshot.getValue(Token.class);
Data data = new Data(fuser.getUid(), R.mipmap.app_icon, username+": "+message, "New Message",
userid);
Sender sender = new Sender(data, token.getToken());
apiService.sendNotification(sender)
.enqueue(new retrofit2.Callback<MyResponse>() {
#Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response)
{
if (response.code() == 200)
{
if (response.body().success != 1)
{
Toast.makeText(ChatActivity.this, "Failed!", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t)
{
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError)
{
}
});
}
}
this is the logcat below
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
at com.paddi.paddi.paddi.ChatActivity.SendMessage(ChatActivity.java:504)
at com.paddi.paddi.paddi.ChatActivity.access$200(ChatActivity.java:58)
at com.paddi.paddi.paddi.ChatActivity$2.onClick(ChatActivity.java:251)
at android.view.View.performClick(View.java:5274)
at android.view.View$PerformClick.run(View.java:21543)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5765)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
You are getting the following error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.auth.FirebaseUser.getUid()' on a null object reference
Because your fuser object is not initialized. To solve this, please add the following line of code in your onCreate() method:
fuser = FirebaseAuth.getInstance().getCurrentUser().getUid();
Hello Guys i need you I have a problem with Firebase Realtime Database I put the data successful to the Firebase but when I try to retrieve it from Firebase I got a problem there is how I put the data
private void user_info(String user_id, String user_display_name) {
mDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(user_id);
HashMap<String, String> userMap = new HashMap<>();
userMap.put("Name",user_display_name);
userMap.put("Balls","30");
userMap.put("Level","1");
mProgressDialog.setMessage("Please Wait...");
mDatabase.setValue(userMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
}
else
Toast.makeText(WelcomeActivity.this, ""+task.getException(), Toast.LENGTH_SHORT).show();
mProgressDialog.dismiss();
}
});
}
And how I try to retrieve the data
private FirebaseUser mUser;
private DatabaseReference mDatabase;
private String level,level1;
private int lev,i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_level_acticity);
//Image
mImg_level1 = (ImageView)findViewById(R.id.mImg_lev1);
mImg_level2 = (ImageView)findViewById(R.id.mImg_lev2);
mImg_level3 = (ImageView)findViewById(R.id.mImg_lev3);
mImg_level4 = (ImageView)findViewById(R.id.mImg_lev4);
mImg_level5 = (ImageView)findViewById(R.id.mImg_lev5);
mImg_level6 = (ImageView)findViewById(R.id.mImg_lev6);
mImg_level7 = (ImageView)findViewById(R.id.mImg_lev7);
mImg_level8 = (ImageView)findViewById(R.id.mImg_lev8);
mImg_level9 = (ImageView)findViewById(R.id.mImg_lev9);
mImg_level10 = (ImageView)findViewById(R.id.mImg_lev10);
mImg_level11 = (ImageView)findViewById(R.id.mImg_lev11);
//Firebase
mUser = FirebaseAuth.getInstance().getCurrentUser();
String user_id = mUser.getUid();
mDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(user_id);
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
level = dataSnapshot.child("Level").getValue().toString();
if (level.equals("1")){
level1 = "1";
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Toast.makeText(this, level1, Toast.LENGTH_SHORT).show();
The toast don't show anything because it null
Change this :-
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
level = dataSnapshot.child("Level").getValue().toString();
if (level.equals("1")){
level1 = "1";
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Toast.makeText(this, level1, Toast.LENGTH_SHORT).show();
to this :-
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
level = dataSnapshot.child("Level").getValue().toString();
if (level.equals("1")){
level1 = "1";
}
Toast.makeText(this, level1, Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The reason this works is that Firebase downloads asynchronously and your code lines execute synchronously.
I have a function which write data into database
private void startCommenting() {
final String comment_val = meditComment.getText().toString().trim();
meditComment.setText("");
if (!TextUtils.isEmpty(comment_val)) {
mProgress.show();
final DatabaseReference newPost = mComment.child(post_key).push();
final String commentkey = newPost.getKey();
mUser.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String,Object> checkoutData=new HashMap<>();
checkoutData.put("time",ServerValue.TIMESTAMP);
newPost.setValue(checkoutData);
newPost.child("comment").setValue(comment_val);
newPost.child("uid").setValue(dataSnapshot.child("id").getValue());
newPost.child("blogpost").setValue(dataSnapshot.child("blogkey").getValue());
newPost.child("userimage").setValue(dataSnapshot.child("image").getValue());
newPost.child("username").setValue(dataSnapshot.child("name").getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
After this function was called, a Query was made to get the data which contains the right post_key in the child ("blogpost").
mpostComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startCommenting();
mQueryCurrentComment = mComment.child(post_key).orderByChild("blogpost").equalTo(post_key);
mQueryCurrentComment.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String currentuserid;
String lastuserid = "";
String currentcommentuid;
for (DataSnapshot dsp : dataSnapshot.getChildren()) {
currentuserid = dsp.child("uid").getValue().toString();
Log.d(TAG, "user newid: " + currentuserid);
Log.d(TAG, "user oldid: " + lastuserid);
if (currentuserid.equals(lastuserid)) {
} else {
final DatabaseReference newCommentLike = mComment.child(currentuserid).push();
Map<String, Object> checkTime = new HashMap<>();
checkTime.put("time", ServerValue.TIMESTAMP);
newCommentLike.setValue(checkTime);
newCommentLike.child("location").setValue(location_key);
newCommentLike.child("category").setValue(category_key);
newCommentLike.child("pressed").setValue("false");
newCommentLike.child("message").setValue(" has also commented your post. ");
newCommentLike.child("blogpost").setValue(post_key);
newCommentLike.child(post_key).setValue(true);
}
lastuserid = currentuserid;
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
However, the Query was triggered twice, one before the new item was added, another after new item was added, which looks like below:
How can I only perform the actions inside Query after the newest item was added and not twice? Any help is appreciated!
In my blog App in post detail Activity i added comments list with simple RecyclerView Adapter that was working fine but i am not able to add delete button for comment so moved to FireBase RecyclerView now i have lots of problems
it not updating in real time
when i comment that not pop out above the edit text layout when i close edit text box then it show my comments
when i write a comment and hit comment button it not show comment but when i writing the second comment on same time after writing three or four line the previous comment pop out and the edit text bot hide under the keyboard why this happening
Activity Code:
mCommentsRecycler.setLayoutManager(mlinearLayoutManager);
}
#Override
public void onStart() {
super.onStart();
// Add value event listener to the post
// [START post_value_event_listener]
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
Post post = dataSnapshot.getValue(Post.class);
// [START_EXCLUDE]
// mAuthorView.setText(post.author);
mTitleView.setText(post.title);
mBodyView.setText(post.body);
final String formImage = String.valueOf(post.postDetailPic);
// [END_EXCLUDE]
if (formImage.length() > 0) {
Picasso.with(getApplicationContext()).load(formImage)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(postPic, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
//Try again online if cache failed
Picasso.with(getApplicationContext())
.load(formImage)
//.error(R.drawable.ic_warning_black_24dp)
.into(postPic, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Log.v("Picasso", "Could not fetch image");
}
});
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
// [START_EXCLUDE]
Toast.makeText(PostDetailActivity.this, "Failed to load post.",
Toast.LENGTH_SHORT).show();
// [END_EXCLUDE]
}
};
mPostReference.addValueEventListener(postListener);
// [END post_value_event_listener]
// Keep copy of post listener so we can remove it when app stops
mPostListener = postListener;
// Listen for comments
mAdapter = new CommentAdepter(Comment.class, CommentViewHolder.class, R.layout.item_comment, mCommentsReference, this);
mCommentsRecycler.setAdapter(mAdapter);
}
#Override
public void onStop() {
super.onStop();
// Remove post value event listener
if (mPostListener != null) {
mPostReference.removeEventListener(mPostListener);
}
// Clean up comments listener
mAdapter.cleanup();
}
#Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.button_post_comment) {
postComment();
}
}
private void postComment() {
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
assert mUser != null;
final String uid = mUser.getUid();
final DatabaseReference commentDb = FirebaseDatabase.getInstance().getReference().child("Users").child(uid);
commentDb.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user information
User user = dataSnapshot.getValue(User.class);
String authorName = user.name;
String commentUserPic = user.ProfilePic;
// Create new comment object
String commentText = mCommentField.getText().toString();
HashMap < String, Object > dateCreated; {
//Otherwise make a new object set to ServerValue.TIMESTAMP
dateCreated = new HashMap < String, Object > ();
dateCreated.put("timeStamp", ServerValue.TIMESTAMP);
}
HashMap < String, Boolean > commenter_id; {
commenter_id = new HashMap < String, Boolean > ();
commenter_id.put(getUid(), true);
}
Comment comment = new Comment(uid, authorName, commentText, commentUserPic, dateCreated, commenter_id);
// Push the comment, it will appear in the list
mCommentsReference.push().setValue(comment);
// Clear the field
mCommentField.setText(null);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private String getUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
private static class CommentViewHolder extends RecyclerView.ViewHolder {
public CommentViewHolder(View itemView) {
super(itemView);
authorView = (TextView) itemView.findViewById(R.id.comment_author);
bodyView = (TextView) itemView.findViewById(R.id.comment_body);
postingTime = (TextView) itemView.findViewById(R.id.comment_post_time);
rm_comment = (Button) itemView.findViewById(R.id.remove_comment);
}
public void setImage(String images) {
this.imageDp = images;
userPic = (ImageView) itemView.findViewById(R.id.comment_photo);
Picasso.with(context).load(imageDp).into(userPic);
}
void bindToPost(Comment comment, View.OnClickListener starClickListener) {
authorView.setText(comment.author);
bodyView.setText(comment.text);
setImage(comment.commentPic);
setViewValue(comment.getTimestampCreatedLong());
rm_comment.setOnClickListener(starClickListener);
}
}
private class CommentAdepter extends FirebaseRecyclerAdapter < Comment, CommentViewHolder > {
private Context mContext;
private List < String > mCommentIds = new ArrayList < > ();
private List < Comment > mComments = new ArrayList < > ();
private String mkey;
CommentAdepter(Class < Comment > CommentClass, Class < CommentViewHolder > viewHolderClass, int modelLayout, DatabaseReference ref, final Context context) {
super(CommentClass, modelLayout, viewHolderClass, mCommentsReference);
mContext = context;
// Create child event listener
// [START child_event_listener_recycler]
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
// A new comment has been added, add it to the displayed list
Comment comment = dataSnapshot.getValue(Comment.class);
// mkey = dataSnapshot.getKey();
// [START_EXCLUDE]
// Update RecyclerView
mCommentIds.add(dataSnapshot.getKey());
mComments.add(comment);
notifyItemInserted(mComments.size() - 1);
// [END_EXCLUDE]
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
Comment newComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int commentIndex = mCommentIds.indexOf(commentKey);
if (commentIndex > -1) {
// Replace with the new data
mComments.set(commentIndex, newComment);
// Update the RecyclerView
notifyItemChanged(commentIndex);
} else {
Log.w(TAG, "onChildChanged:unknown_child:" + commentKey);
}
// [END_EXCLUDE]
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
// A comment has changed, use the key to determine if we are displaying this
// comment and if so remove it.
String commentKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int commentIndex = mCommentIds.indexOf(commentKey);
if (commentIndex > -1) {
// Remove data from the list
mCommentIds.remove(commentIndex);
mComments.remove(commentIndex);
// Update the RecyclerView
notifyItemRemoved(commentIndex);
} else {
Log.w(TAG, "onChildRemoved:unknown_child:" + commentKey);
}
// [END_EXCLUDE]
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
// A comment has changed position, use the key to determine if we are
// displaying this comment and if so move it.
Comment movedComment = dataSnapshot.getValue(Comment.class);
String commentKey = dataSnapshot.getKey();
// ...
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w("PostDetailActivity", "postComments:onCancelled", databaseError.toException());
Toast.makeText(mContext, "Failed to load comments.",
Toast.LENGTH_SHORT).show();
}
};
ref.addChildEventListener(childEventListener);
// [END child_event_listener_recycler]
// Store reference to listener so it can be removed on app stop
}
#Override
public int getItemCount() {
return mComments.size();
}
#Override
protected void populateViewHolder(final CommentViewHolder viewHolder, final Comment model, final int position) {
final DatabaseReference commentRef = getRef(position);
final String commentKey = commentRef.getKey();
if (model.commenter_id.containsKey(gUid())) {
viewHolder.rm_comment.setVisibility(View.VISIBLE);
}
viewHolder.bindToPost(model, new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(mContext, "clicked " + commentKey, Toast.LENGTH_SHORT).show();
mCommentsReference.child(commentKey).removeValue();
}
});
}
}
private String gUid() {
return FirebaseAuth.getInstance().getCurrentUser().getUid();
}
}
if u need layout file please comment....
I added ability to delete an item in a FirebaseRecyclerAdapter and generally followed the advice in this post:
how to implement a SetOnItemClickListener FirebaseRecyclerViewAdapter
I used the first solution, adding an ImageView.setOnClickListener() call within populateViewHolder(). Its working fine for me.
I'm not quite sure what the #3 problem is above but I was having a problem whereby the data didn't get populated the first time it was called. I found my solution in this post, namely ensuring that the RecyclerView height was set to match_parent:
FirebaseRecyclerAdapter - populateViewHolder is not populating the data for first time it runs?