I have a feed with posts from different users that is built using the FirebaseRecyclerAdapter.
It works fine but when i change a user's profile picture i want the profile picture from all of that user's posts to change as well.
At the moment it just displays the profile picture that was present at the moment the post was created.
Here is the code:
I call chooseImage when i click the upload button:
private void chooseImage() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
startActivityForResult(intent, PICK_IMAGE_REQUEST);
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK
&& data != null && data.getData() != null) {
imageUri = data.getData();
uploadImage();
}
}
private void uploadImage() {
if (imageUri != null) {
StorageReference fileReference = storageReference
.child(FirebaseAuth.getInstance().getCurrentUser().getUid() + "." + getImageExtension(imageUri));
fileReference.putFile(imageUri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Handler handler = new Handler();
Picasso.with(getContext()).load(imageUri).into(imgProfile);
handler.postDelayed(new Runnable() {
#Override
public void run() {
progressBar.setProgress(0);
progressBar.setVisibility(View.GONE);
}
}, 1000);
Toast.makeText(getActivity(), "Image changed successfully", Toast.LENGTH_LONG).show();
databaseReference.child("profilePic").setValue(taskSnapshot.getStorage().getDownloadUrl().toString());
UserProfileChangeRequest profileChangeRequest = new UserProfileChangeRequest.Builder()
.setPhotoUri(imageUri)
.build();
user.updateProfile(profileChangeRequest);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(#NonNull UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount());
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress((int) progress);
}
});
} else {
Toast.makeText(this.getContext(), "No image selected", Toast.LENGTH_SHORT).show();
}
}
This is how i add the posts:
btnPostComm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String story = et.getText().toString();
String title = et2.getText().toString();
String key = refference.push().getKey();
String name = user.getDisplayName();
String uri = user.getPhotoUrl().toString();
CommModel model = new CommModel(
story,
title,
name,
uri
);
refference
.child(key)
.setValue(model);
}
});
This is my Model class:
public class CommModel {
private String story;
private String title;
private String name;
private String uri;
public CommModel(){}
public CommModel(String story, String title, String name, String uri) {
this.story = story;
this.title = title;
this.name = name;
this.uri = uri;
}
public String getStory() {
return story;
}
public void setStory(String story) {
this.story = story;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
}
This is the ViewHolder:
public class PostsViewHolder extends RecyclerView.ViewHolder {
public TextView txtStory;
public TextView txtTitle;
public TextView txtName;
public CircularImageView proImage;
public QNAViewHolder(#NonNull View itemView) {
super(itemView);
txtStory = itemView.findViewById(R.id.txtStory);
txtTitle = itemView.findViewById(R.id.txtTitle);
txtName = itemView.findViewById(R.id.txtName1);
proImage = itemView.findViewById(R.id.profile3);
}
}
And this is the Adapter in the Fragment that hosts the RecyclerView:
public void showPosts() {
FirebaseRecyclerOptions options = new FirebaseRecyclerOptions.Builder<CommModel>()
.setQuery(ref, CommModel.class)
.build();
adpt = new FirebaseRecyclerAdapter<CommModel, PostsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull PostsViewHolder holder, int position, #NonNull CommModel model) {
holder.txtStory.setText(model.getStory());
holder.txtTitle.setText(model.getTitle());
holder.txtName.setText(model.getName());
Glide.with(Posts.this).load(model.getUri()).into(holder.proImage);
}
#Override
public int getItemCount() {
return super.getItemCount();
}
#Override
public void onDataChanged() {
recyclerView.removeAllViews();
super.onDataChanged();
}
#NonNull
#Override
public CommModel getItem(int position) {
return super.getItem(getItemCount() - 1 - position);
}
#NonNull
#Override
public PostsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.qna_feed, parent, false);
return new PostsViewHolder(view);
}
};
adpt.startListening();
adpt.notifyDataSetChanged();
recyclerView.setAdapter(adpt);
}
How can i update the pictures on every post of a user when he changes his profile pic?
Thank you very much!
If you want to do that, you have to change the CommModel class. You need to add another property, such as userUid.
private String story;
private String title;
private String name;
private String uri;
private String userUid; //Create new one and getter setter too
After that, at your showPosts method, you can call the user's property and get his profile picture.
holder.txtStory.setText(model.getStory());
holder.txtTitle.setText(model.getTitle());
holder.txtName.setText(model.getName());
final String userUid = model.getUserUid();
//Call Firebase to get user current profile.
FirebaseDatabase.getInstance().getReference().child("User").child(userUid).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exist()){
final String pictureUrl = dataSnapshot.chilld("profilePic").getValue(String.class);
Glide.with(Posts.this).load(pictureUrl).into(holder.proImage);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Related
Hi I want the chat message Align like this when I send message I want them on the right when I receive I want them on left like this in the image
but it looks like this even though I set to two different layouts for in and out but it appears in the same way
In ChatRoomActvity getItemViewType(int position) always return as MESSAGE_IN_VIEW_TYPE;
What am I missing here?
ChatRoomActvity.java
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirebaseUser;
private DatabaseReference mFirebaseDatabaseReference;
private FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder>
mFirebaseAdapter;
public static final String MESSAGES_CHILD = "messages";
public static final String ANONYMOUS = "anonymous";
private static final String TAG = "ChatRoomAct";
private static final int REQUEST_IMAGE = 2;
private static final String LOADING_IMAGE_URL = "https://www.google.com/images/spin-32.gif";
private FloatingActionButton mSendButton;
private RecyclerView mMessageRecyclerView;
private LinearLayoutManager mLinearLayoutManager;
private ProgressBar mProgressBar;
private EditText mMessageEditText;
private ImageView mAddMessageImageView;
private String mUsername;
private String mPhotoUrl;
private String mUserid;
private String mSenderUid;
//Emoji Function
private ImageView emojiButton;
private EmojiPopup emojiPopup;
private ViewGroup rootView;
private EmojiEditText editText;
private final int MESSAGE_IN_VIEW_TYPE = 1;
private final int MESSAGE_OUT_VIEW_TYPE = 2;
public static class MessageViewHolder extends RecyclerView.ViewHolder {
TextView mTime;
CircleImageView imgProfile;
TextView messageTextView;
ImageView messageImageView;
TextView messengerTextView;
CircleImageView messengerImageView;
TextView mLikesCount;
ImageView imgDropdown, imgLikes;
public MessageViewHolder(View v) {
super(v);
messengerTextView = (TextView) itemView.findViewById(R.id.message_user);
messageTextView = (TextView) itemView.findViewById(R.id.message_text);
mTime = (TextView) itemView.findViewById(R.id.message_time);
messengerImageView = (CircleImageView) itemView.findViewById(R.id.imgDps);
imgLikes = itemView.findViewById(R.id.imgLikes);
mLikesCount = (TextView)itemView.findViewById(R.id.message_Likes);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_room_actvity);
// Initialize ProgressBar and RecyclerView.
mProgressBar = (ProgressBar) findViewById(R.id.loader);
mMessageRecyclerView = (RecyclerView) findViewById(R.id.list);
mLinearLayoutManager = new LinearLayoutManager(ChatRoomActvity.this);
mLinearLayoutManager.setStackFromEnd(true);
mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = mFirebaseAuth.getCurrentUser();
mUserid = mFirebaseUser.getUid();
mUsername = ANONYMOUS;
if (mFirebaseUser == null) {
finish();
return;
} else {
mUsername = mFirebaseUser.getDisplayName();
if (mFirebaseUser.getPhotoUrl() != null) {
mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();
}
}
displaychatmessages();
}
public void displaychatmessages() {
mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
SnapshotParser<FriendlyMessage> parser = new SnapshotParser<FriendlyMessage>() {
#NonNull
#Override
public FriendlyMessage parseSnapshot(DataSnapshot snapshot) {
FriendlyMessage friendlyMessage = snapshot.getValue(FriendlyMessage.class);
if (friendlyMessage != null) {
friendlyMessage.setId(snapshot.getKey());
}
return friendlyMessage;
}
};
DatabaseReference messagesRef = mFirebaseDatabaseReference.child(MESSAGES_CHILD);
FirebaseRecyclerOptions<FriendlyMessage> options =
new FirebaseRecyclerOptions.Builder<FriendlyMessage>()
.setQuery(messagesRef, parser)
.build();
mFirebaseAdapter = new FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder>(options) {
#Override
public int getItemViewType(int position) {
if(getItem(position).getId().equals(mFirebaseAuth.getCurrentUser().getUid()))
{
return MESSAGE_OUT_VIEW_TYPE;
} else {
return MESSAGE_IN_VIEW_TYPE;
}
}
#Override
protected void onBindViewHolder(MessageViewHolder viewHolder, int position, FriendlyMessage friendlyMessage) {
mProgressBar.setVisibility(ProgressBar.INVISIBLE);
if (friendlyMessage.getText() != null) {
viewHolder.messageTextView.setText(friendlyMessage.getText());
viewHolder.messageTextView.setVisibility(TextView.VISIBLE);
viewHolder.mTime.setText(DateFormat.format("dd MMM (h:mm a)", friendlyMessage.getMessageTime()));
viewHolder.mLikesCount.setText(String.valueOf(friendlyMessage.getMessageLikesCount()));
if (friendlyMessage.getMessageLikes() != null) {
if (friendlyMessage.getMessageLikes().containsValue(mUserid)) {
viewHolder.imgLikes.setImageResource(R.drawable.red_heart);
} else {
viewHolder.imgLikes.setImageResource(R.drawable.chat_heart);
}
}
}
viewHolder.messengerTextView.setText(friendlyMessage.getName());
if (friendlyMessage.getPhotoUrl() == null) {
viewHolder.messengerImageView.setImageDrawable(ContextCompat.getDrawable(ChatRoomActvity.this,
R.drawable.profile));
} else {
Glide.with(ChatRoomActvity.this)
.load(friendlyMessage.getPhotoUrl())
.into(viewHolder.messengerImageView);
}
}
#NonNull
#Override
public MessageViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = null;
if(i==MESSAGE_IN_VIEW_TYPE){
view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.message_in, viewGroup, false);
}
else if(i==MESSAGE_OUT_VIEW_TYPE){
view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.message_out, viewGroup, false);
}
return new MessageViewHolder(view);
}
};
mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = mFirebaseAdapter.getItemCount();
int lastVisiblePosition =
mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
// If the recycler view is initially being loaded or the
// user is at the bottom of the list, scroll to the bottom
// of the list to show the newly added message.
if (lastVisiblePosition == -1 ||
(positionStart >= (friendlyMessageCount - 1) &&
lastVisiblePosition == (positionStart - 1))) {
mMessageRecyclerView.scrollToPosition(positionStart);
}
}
});
mMessageRecyclerView.setAdapter(mFirebaseAdapter);
mMessageEditText = (EditText) findViewById(R.id.input);
mMessageEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length() > 0) {
mSendButton.setEnabled(true);
} else {
mSendButton.setEnabled(false);
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
mSendButton = (FloatingActionButton) findViewById(R.id.btnSend);
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FriendlyMessage friendlyMessage = new
FriendlyMessage(mUserid,mMessageEditText.getText().toString(),null,
mUsername,
mPhotoUrl,
null /* no image */);
mFirebaseDatabaseReference.child(MESSAGES_CHILD)
.push().setValue(friendlyMessage);
mMessageEditText.setText("");
}
});
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onResume() {
super.onResume();
mFirebaseAdapter.startListening();
}
#Override
protected void onPause() {
super.onPause();
mFirebaseAdapter.stopListening();
}
#Override
protected void onStop() {
super.onStop();
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: requestCode=" + requestCode + ", resultCode=" + resultCode);
if (requestCode == REQUEST_IMAGE) {
if (resultCode == RESULT_OK) {
if (data != null) {
final Uri uri = data.getData();
Log.d(TAG, "Uri: " + uri.toString());
FriendlyMessage tempMessage = new FriendlyMessage(null,null,null,mUsername, mPhotoUrl,
LOADING_IMAGE_URL);
mFirebaseDatabaseReference.child(MESSAGES_CHILD).push()
.setValue(tempMessage, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError,
DatabaseReference databaseReference) {
if (databaseError == null) {
String key = databaseReference.getKey();
StorageReference storageReference =
FirebaseStorage.getInstance()
.getReference(mFirebaseUser.getUid())
.child(key)
.child(uri.getLastPathSegment());
putImageInStorage(storageReference, uri, key);
} else {
Log.w(TAG, "Unable to write message to database.",
databaseError.toException());
}
}
private void putImageInStorage(StorageReference storageReference, Uri uri, String key) {
storageReference.putFile(uri).addOnCompleteListener(ChatRoomActvity.this,
new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
task.getResult().getMetadata().getReference().getDownloadUrl()
.addOnCompleteListener(ChatRoomActvity.this,
new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
FriendlyMessage friendlyMessage =
new FriendlyMessage(null,null,null, mUsername, mPhotoUrl,
task.getResult().toString());
mFirebaseDatabaseReference.child(MESSAGES_CHILD).child(key)
.setValue(friendlyMessage);
}
}
});
} else {
Log.w(TAG, "Image upload task was not successful.",
task.getException());
}
}
});
}
});
}
}
}
}
}
FriendlyMessage.java
public class FriendlyMessage {
private String id;
private String text;
private String name;
private String photoUrl;
private String imageUrl;
private long messageTime;
private long messageLikesCount;
private Map<String, Boolean> messageLikes = new HashMap<>();
public FriendlyMessage(){}
public FriendlyMessage(String id,String text,String name, String photoUrl, String imageUrl) {
this.id = id;
this.text = text;
this.name = name;
messageTime = new Date().getTime();
this.photoUrl = photoUrl;
this.imageUrl = imageUrl;
this.messageLikesCount = messageLikesCount;
this.messageLikes= messageLikes;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setText(String text) {
this.text = text;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhotoUrl() {
return photoUrl;
}
public String getText() {
return text;
}
public void setPhotoUrl(String photoUrl) {
this.photoUrl = photoUrl;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public long getMessageTime() {
return messageTime;
}
public void setMessageTime(long messageTime) {
this.messageTime = messageTime;
}
public long getMessageLikesCount() {
return messageLikesCount;
}
public void setMessageLikesCount(long messageLikesCount) {
this.messageLikesCount = messageLikesCount;
}
public Map<String, Boolean> getMessageLikes() {
return messageLikes;
}
public void setMessageLikes(Map<String, Boolean> messageLikes) {
this.messageLikes = messageLikes;
}
}
I can't without the images (for any reason, they are not in the post) but from what I see,
getItem(position).getId().equals(mFirebaseAuth.getCurrentUser().getUid())
and
FriendlyMessage.getId()
I'd say you're not taking the sender into account. ID is conventionally used as a message number, they usually do not point to a uid. Besides, your class already has a field called senderUid, so you should compare against that instead of id.
Optionally, try to log the line before the condition.
#Override
public int getItemViewType(int position) {
FriendlyMessage friendlyMessage = getItem(position);
boolean user = (friendlyMessage.getUserid().equals(mUserid));
if(user)
{
return MESSAGE_OUT_VIEW_TYPE;
} else {
return MESSAGE_IN_VIEW_TYPE;
}
}
I use boolean
I am trying to retrive data using a recylerView, but I keep getting an error in regards to this line Upload upload=postsnapshot.getValue(Upload.class); but it's not telling me what the problem is exaclty and plus I get another error saying this E/FirebaseInstanceId: Token retrieval failed: INVALID_SENDER I'm not sure what's going on. Here is my code below. Any help will be appricated. Thanks in advance
//Log cat error
2020-03-31 17:15:47.842 1943-1943/? E/FirebaseInstanceId: binding to the service failed
//This my model class
public class Upload {
private String mImageUrl;
private String nickName;
private String fullname;
private String age;
private String height;
public Upload(){
//Empty constructor needed
}
public Upload(String imageUrl ){
mImageUrl=imageUrl;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
public String getmImageUrl() {
return mImageUrl;
}
public void setmImageUrl(String mImageUrl) {
this.mImageUrl = mImageUrl;
}
//My adapter class
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder>{
private Context mContext;
private List<Upload> mUploads;
public ImageAdapter(Context context, List<Upload> uploads){
mContext = context;
mUploads = uploads;
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View V = LayoutInflater.from(mContext).inflate(R.layout.cardview, parent, false);
return new ImageViewHolder(V);
}
#Override
public void onBindViewHolder(#NonNull ImageViewHolder holder, int position) {
Upload uploadCurrent=mUploads.get(position);
holder.txt1.setText(uploadCurrent.getnickName());
Picasso.get().load(String.valueOf(uploadCurrent)).fit().centerCrop().into(holder.imageView);
}
#Override
public int getItemCount() {
return mUploads.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder{
public ImageView imageView;
public TextView txt1;
public ImageViewHolder(#NonNull View itemView) {
super(itemView);
imageView=itemView.findViewById(R.id.imageview);
txt1=itemView.findViewById(R.id.nickname);
}
}
//This the main page
databaseReference.child(uid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postsnapshot : dataSnapshot.getChildren()) {
Upload upload=postsnapshot.getValue(Upload.class);
mUploads.add(upload);
}
mAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(MainActivity.this, databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});
//This class is where they upload their image
storageRef.putFile(filepath).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//Toast.makeText(UploadAdActivity.this,"Uploaded successfully",Toast.LENGTH_LONG).show();
//Upload upload=new Upload(taskSnapshot.getStorage().getDownloadUrl().toString());
//String uploadId=update.push().getKey();
//update.child(uploadId).setValue(upload);
progressDialog.dismiss();
Toast.makeText(UploadAdActivity.this,"Uploaded successfully",Toast.LENGTH_LONG).show();
storageReference.getDownloadUrl().toString();
taskSnapshot.getStorage().getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String download_url=uri.toString();
Upload upload=new Upload(download_url);
String uploadId=update.push().getKey();
// String a=update.push().getKey();
Intent d=new Intent(UploadAdActivity.this,AllInOneActivity.class);
d.putExtra("a",uploadId);
update.child(uploadId).setValue(upload);
Intent i = new Intent(UploadAdActivity.this, NextPage.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
i.putExtra("a",uploadId);
startActivity(i);
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(UploadAdActivity.this,"Failed to upload",Toast.LENGTH_LONG).show();
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot
.getTotalByteCount());
progressDialog.setMessage("Uploaded "+(int)progress+"%");
}
});
I have a recycler view setup for my chat app. I would like to add it so users are able to send pictures in the chat. I added an image view and added the code to upload the image to firestore. Where I am confused is implementing the code to display it in the recycler view.
Model:
package com.example.android.debateapp.Message;
public class Message {
private String ChatMessage;
private String mChatImageURL;
public Message(){
//Empty constructor needed
}
public Message(String ChatMessage, String mChatImageURL ){
this.ChatMessage = ChatMessage;
this.mChatImageURL = mChatImageURL;
}
public String getChatMessage() {
return ChatMessage;
}
public String getmChatImageURL() {
return mChatImageURL;
}
}
MessageRecyclerAdapter:
public class MessageRecyclerAdapter extends FirestoreRecyclerAdapter<Message, MessageRecyclerAdapter.MessageHolder> {
public MessageRecyclerAdapter(#NonNull FirestoreRecyclerOptions<Message> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull MessageHolder holder, int position, #NonNull Message model) {
holder.ChatMessage.setText(model.getChatMessage());
}
#NonNull
#Override
public MessageHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.message_item, viewGroup, false);
return new MessageHolder(v);
}
class MessageHolder extends RecyclerView.ViewHolder{
TextView ChatMessage;
CircleImageView MessageProfilePicture;
ImageView ChatMessageImage;
public MessageHolder(#NonNull View itemView) {
super(itemView);
ChatMessage = itemView.findViewById(R.id.Message_Chat_Content);
MessageProfilePicture = itemView.findViewById(R.id.Chat_Profile_picture);
ChatMessageImage = itemView.findViewById(R.id.chat_Message_image);
}
public void setChatImage(final String downloadUri) {
ChatMessageImage = itemView.findViewById(R.id.chat_Message_image);
Glide.with(itemView.getContext()).load(downloadUri).into(ChatMessageImage);
}
}
}
ChatActivity
public class ChatActivity extends AppCompatActivity {
public static final int DEFAULT_MSG_LENGTH_LIMIT = 1000;
private static final int GALLERY_PICK = 1;
private ListView mMessageListView;
private ImageButton mPhotoPickerButton;
private EditText mMessageEditText;
private Button mSendButton;
private String mUsername;
private ChildEventListener mChildEventListner;
private ValueEventListener mValueEventListner;
private FirebaseUser mCurrentUser;
private StorageReference storageReference;
private StorageReference mChatPhotosStorageReference;
private Context mContext;
private MessageRecyclerAdapter adapter;
private ImageView chatimage;
private String TESTmessagedoc;
private ImageView chatProfile;
//FIRE STORE
private DocumentReference mMessageDoc;
private FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();
private CollectionReference collectionReference = (firebaseFirestore).collection("Messages");
private CollectionReference colRef;
private static final String TAG = ChatActivity.class.getName();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_activity);
storageReference = FirebaseStorage.getInstance().getReference();
chatProfile = findViewById(R.id.Chat_Profile_picture);
//chatimage = findViewById(R.id.photoImageView);
final String messageDoc = getIntent().getStringExtra("Message_ID");
TESTmessagedoc = messageDoc;
mMessageDoc = firebaseFirestore.collection("Messages").document(messageDoc);
colRef = firebaseFirestore.collection("Messages").document(messageDoc).collection("chats");
mPhotoPickerButton = (ImageButton) findViewById(R.id.photoPickerButton);
mMessageEditText = (EditText) findViewById(R.id.messageEditText);
mSendButton = (Button) findViewById(R.id.sendButton);
mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
final String current_uid = mCurrentUser.getUid();
// ImagePickerButton shows an image picker to upload a image for a message
mPhotoPickerButton.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);
}
});
setUpRecyclerView();
// Enable Send button when there's text to send
mMessageEditText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length() > 0) {
mSendButton.setEnabled(true);
} else {
mSendButton.setEnabled(false);
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(DEFAULT_MSG_LENGTH_LIMIT)});
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String MessageText = mMessageEditText.getText().toString();
Map<String, Object> chatMap = new HashMap<>();
chatMap.put("ChatMessage", MessageText);
chatMap.put("User ID", current_uid);
chatMap.put("Timestamp", FieldValue.serverTimestamp());
firebaseFirestore.collection("Messages")
.document(messageDoc).collection("chats")
.add(chatMap)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
// Clear input box
mMessageEditText.setText("");
}
});
}
private void setUpRecyclerView() {
Query query = colRef.orderBy("Timestamp", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<Message> options = new FirestoreRecyclerOptions.Builder<Message>()
.setQuery(query, Message.class)
.build();
adapter = new MessageRecyclerAdapter(options);
RecyclerView recyclerView = findViewById(R.id.recycler_message_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_PICK && resultCode == RESULT_OK) {
String imageUri = data.getDataString();
CropImage.activity(Uri.parse(imageUri))
.setAspectRatio(1, 1)
.start(this);
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK) {
Uri resultUri = result.getUri();
final String current_user_id = mCurrentUser.getUid();
final String randomName = UUID.randomUUID().toString();
final StorageReference filepath = storageReference.child("chat_photos").child(randomName + ".JPG");
filepath.putFile(resultUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
filepath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
final String downloadUrl = uri.toString();
Map<String, String> newImageUrl = new HashMap<>();
newImageUrl.put("image", downloadUrl);
firebaseFirestore.collection("Messages").document(TESTmessagedoc).collection("chats")
.add(newImageUrl)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
/*
filepath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
//The download url
final String downloadUrl =
uri.toString();
Log.d("tag", downloadUrl);
if (!downloadUrl.equals("default")) {
// I changed this to glide since i thought picasso was the problem.
// Picasso still should work. Glide is recommended by google tho
Glide.with(getApplicationContext()).load(downloadUrl).into(chatProfile);
}
}
});
*/
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(), "There was some error in saving Changes.", Toast.LENGTH_LONG).show();
}
});
}
});
}
});
}
}
}}
In the model class i have added getmChatImageURL
In the MessageRecyclerAddapter i added setChatImage
where i am stuck (i think) is in my MessageRecyclerAdapter on my onBindViewHolder i need to set it but i am unsure on how to go about it because i dont know how i would load it into the drawable
Update:
In my MessageRecyclerAdapter i added this
#Override
protected void onBindViewHolder(#NonNull MessageHolder holder, int position, #NonNull Message model) {
holder.ChatMessage.setText(model.getChatMessage());
holder.setChatImage(model.getmChatImageURL());
}
the app run but when i go to upload a image to firestore and the app attempts to display it i get this in the log
W/Glide: Load failed for null with size [0x0]
class com.bumptech.glide.load.engine.GlideException: Received null model
the image is being stored in firestore as a url so i believe the error has something to do with the adapter setup not sure though.
Update 2
I think im on the right track
i changed my adapter class
MessageRecyclerAdapter:
public class MessageRecyclerAdapter extends FirestoreRecyclerAdapter<Message, MessageRecyclerAdapter.MessageHolder> {
private Context mcontext;
public MessageRecyclerAdapter(#NonNull FirestoreRecyclerOptions<Message> options ) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull MessageHolder holder, int position, #NonNull Message model) {
holder.ChatMessage.setText(model.getChatMessage());
Glide.with(mcontext.getApplicationContext())
.load(model.getmChatImageURL())
.into(holder.ChatMessageImage);
}
#NonNull
#Override
public MessageHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.message_item, viewGroup, false);
return new MessageHolder(v);
}
class MessageHolder extends RecyclerView.ViewHolder{
TextView ChatMessage;
CircleImageView MessageProfilePicture;
ImageView ChatMessageImage;
public MessageHolder(#NonNull View itemView) {
super(itemView);
ChatMessage = itemView.findViewById(R.id.Message_Chat_Content);
MessageProfilePicture = itemView.findViewById(R.id.Chat_Profile_picture);
ChatMessageImage = itemView.findViewById(R.id.chat_Message_image);
}
}
}
i added the glide set image into the onbind the error i am facing now when running the code is
android.content.Context android.content.Context.getApplicationContext()' on a null object reference
I also tried
Glide.with(holder.ChatMessageImage.getContext())
.load(model.getmChatImageURL())
.into(holder.ChatMessageImage);
the app runs i am able to successfully upload an image to firestore but then glide throws
W/Glide: Load failed for null with size [0x0]
class com.bumptech.glide.load.engine.GlideException: Received null model
im unsure on how to debug this because when i hook the debugger up to the glide code in the onbind it triggers as soon as the activity is launched
If you already know the imageUrl then just pass it in like this
#Override
protected void onBindViewHolder(#NonNull MessageHolder holder, int position, #NonNull Message model) {
holder.ChatMessage.setText(model.getChatMessage());
holder.setChatImage(imageUrl)
}
I am using Firebase-UI to load images from Firebase Storage url string from Firestore and shown into RecyclerView using Picasso.
I have 2 variables in the database : name and image url the name appears in the recyclerview but the image not what is the problem that makes image does not appear.
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/text_view_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:text="Name"
android:textColor="#android:color/black"
android:textSize="20sp" />
<ImageView
android:id="#+id/image_view_upload"
android:layout_width="match_parent"
android:layout_height="200dp" />
</LinearLayout>
public class Upload {
private String mName;
private String mImageUrl;
public Upload() {
//empty constructor needed
}
public Upload(String name, String imageUrl) {
if (name.trim().equals("")) {
name = "No Name";
}
mName = name;
mImageUrl = imageUrl;
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public String getImageUrl() {
return mImageUrl;
}
public void setImageUrl(String imageUrl) {
mImageUrl = imageUrl;
}
}
package com.example.amr.firebasestorage;
public class ImageActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private FirebaseFirestore firebaseFirestor;
private FirestoreRecyclerAdapter<Upload, ImageActivity.ImageViewHolder>
Adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image);
//=========firebase==============
firebaseFirestor = FirebaseFirestore.getInstance();
//===============================
//==========Recycler Items========
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Query query = firebaseFirestor.collection("uploads")
;
FirestoreRecyclerOptions<Upload> options = new FirestoreRecyclerOptions.Builder<Upload>()
.setQuery(query, Upload.class)
.build();
Adapter = new FirestoreRecyclerAdapter<Upload, ImageViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull ImageViewHolder holder, int
position, #NonNull Upload model) {
holder.setName(model.getName());
holder.setImageUrl(model.getImageUrl());
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.image_item, parent, false);
return new ImageViewHolder(view);
}
};
recyclerView.setAdapter(Adapter);
}
public class ImageViewHolder extends RecyclerView.ViewHolder {
public TextView textViewName;
public ImageView imageView;
View mView;
public ImageViewHolder(View itemView) {
super(itemView);
mView=itemView;
imageView = mView.findViewById(R.id.image_view_upload);
}
public void setName(String name) {
textViewName = mView.findViewById(R.id.text_view_name);
textViewName.setText(name);
}
public void setImageUrl(String imageUrl) {
imageView = mView.findViewById(R.id.image_view_upload);
Picasso.get()
.load(imageUrl)
.fit()
.into(imageView);
}
}
#Override
public void onStart() {
super.onStart();
Adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
if ( Adapter != null ) {
Adapter.stopListening();
}
}
}
//main activity
public class MainActivity extends AppCompatActivity {
private static final int PICK_IMAGE_REQUEST = 1;
private Button mButtonChooseImage;
private Button mButtonUpload;
private TextView mTextViewShowUploads;
private EditText mEditTextFileName;
private ImageView mImageView;
private ProgressBar mProgressBar;
private Uri mImageUri;
//_________
private StorageTask storageTask;
private StorageReference storageReference;
private DocumentReference firebaseFirestore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButtonChooseImage = findViewById(R.id.button_choose_image);
mButtonUpload = findViewById(R.id.button_upload);
mTextViewShowUploads = findViewById(R.id.text_view_show_uploads);
mEditTextFileName = findViewById(R.id.edit_text_file_name);
mImageView = findViewById(R.id.image_view);
mProgressBar = findViewById(R.id.progress_bar);
//________
storageReference = FirebaseStorage.getInstance().getReference("uploads");
firebaseFirestore = FirebaseFirestore.getInstance().collection("uploads").document();
mButtonChooseImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openFileChooser();
}
});
mButtonUpload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if ( storageTask != null && storageTask.isInProgress() ) {
Toast.makeText(MainActivity.this, "wait", Toast.LENGTH_SHORT).show();
} else {
uploadFiles();
}
}
});
mTextViewShowUploads.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openImagesActivity();
}
});
}
private void openImagesActivity() {
Intent inten = new Intent(this, ImageActivity.class);
startActivity(inten);
}
private String getFileExtension(Uri uri) {
ContentResolver contentResolver = getContentResolver();
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
return mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(uri));
}
private void uploadFiles() {
if ( mImageUri != null ) {
StorageReference fileRef = storageReference
//
.child(System.currentTimeMillis() + "." + getFileExtension(mImageUri));
//.child("Photos").child(mImageUri.getLastPathSegment());
storageTask = fileRef.putFile(mImageUri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mProgressBar.setProgress(0);
}
}, 500);
Toast.makeText(MainActivity.this, "Upload succesful", Toast.LENGTH_SHORT).show();
Uri downloadUri = taskSnapshot.getUploadSessionUri();
assert downloadUri != null;
Upload upload = new Upload(mEditTextFileName
.getText().toString().trim()
, downloadUri.toString());
firebaseFirestore.set(upload);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount());
mProgressBar.setProgress((int) progress);
}
});
} else {
Toast.makeText(this, "No file selected", Toast.LENGTH_SHORT).show();
}
}
public void openFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, PICK_IMAGE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ( requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK
&& data != null && data.getData() != null ) {
mImageUri = data.getData();//something back
Picasso.get().load(mImageUri).into(mImageView);
}
}
}
my database
my mobile pic
The problem lies in the fact that you have an incorrect getter for mName field in your model class. When you are using getName() as a getter, Firebase is looking after a field named name and not mName, as it is in your code now. See the difference? The correct model class should look like this:
public class Upload {
private String name;
private String imageUrl;
public Upload() {}
public Upload(String name, String imageUrl) {
this.name = name;
this.imageUrl = imageUrl;
}
public String getName() { return name; }
public String getImageUrl() { return imageUrl; }
}
The setters are not required, are always optional because if there is no setter for a JSON property, the Firebase client will set the value directly onto the field. But if you wish to use setters, the correct setters for your fields are:
public void setName(String name) { this.name = name; }
public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; }
I fixed it
the problem was not in setter and getter but it was here
Uri downloadUri = taskSnapshot.getUploadSessionUri();
it is not the right link to show i replaced it by this
Uri downloadUri = taskSnapshot.getDownloadUrl();
works perfectly
I followed a Tutorial and was Successfully able to Load the data in Firebase and also retrieve it back in RecyclerView and also Learned How to Delete data but now I'm Stuck that how to update this data in the Firebase and show it in RecyclerView.I have used Picasso for the Images.
This is my Gallery.java file
public class Gallery extends AppCompatActivity {
private static final int PICK_IMAGE_REQUEST= 1;
private Button mButtonChooseImage;
private Button mButtonUpload;
private TextView mTextViewShowGallery;
private EditText mEditTextFileName,mEditTextDesc;
private ImageView mImageView;
private ProgressBar mProgressBar;
private Uri mImageUri;
private StorageReference mStorageRef;
private DatabaseReference mDatabaseRef;
private StorageTask mUploadTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
mButtonChooseImage = (Button)findViewById(R.id.btnChoose);
mButtonUpload = (Button)findViewById(R.id.btnUpload);
mTextViewShowGallery = (TextView)findViewById(R.id.tvShow);
mImageView = (ImageView)findViewById(R.id.imgView);
mProgressBar = (ProgressBar)findViewById(R.id.progress_bar);
mEditTextFileName = (EditText)findViewById(R.id.txtName);
mEditTextDesc = (EditText)findViewById(R.id.txtDesc);
mStorageRef = FirebaseStorage.getInstance().getReference("uploads");
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
mButtonChooseImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openFileChooser();
}
});
mButtonUpload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mUploadTask != null && mUploadTask.isInProgress())
{
Toast.makeText(Gallery.this, "Upload In Progress", Toast.LENGTH_SHORT).show();
}
else
{
uploadFile();
}
}
});
mTextViewShowGallery.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openImagesActivity();
}
});
}
private void openFileChooser ()
{
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,PICK_IMAGE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK
&& data != null && data.getData() != null)
{
mImageUri = data.getData();
Picasso.with(this).load(mImageUri).into(mImageView);
}
}
private String getFileExtension(Uri uri)
{
ContentResolver cR = getContentResolver();
MimeTypeMap mime = MimeTypeMap.getSingleton();
return mime.getExtensionFromMimeType(cR.getType(uri));
}
private void uploadFile()
{
if (mImageUri != null)
{
StorageReference fileReference = mStorageRef.child(System.currentTimeMillis()
+ "." + getFileExtension(mImageUri));
mUploadTask = fileReference.putFile(mImageUri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mProgressBar.setProgress(0);
}
},500);
Toast.makeText(Gallery.this, "Upload Successful", Toast.LENGTH_LONG).show();
UploadImage uploadImage = new UploadImage(mEditTextFileName.getText().toString().trim(),
mEditTextDesc.getText().toString().trim(),taskSnapshot.getDownloadUrl().toString());
String uploadId = mDatabaseRef.push().getKey();
mDatabaseRef.child(uploadId).setValue(uploadImage);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(Gallery.this,e.getMessage(), Toast.LENGTH_SHORT).show();
}
})
.addOnPausedListener(new OnPausedListener<UploadTask.TaskSnapshot>() {
#Override
public void onPaused(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount());
mProgressBar.setProgress((int)progress);
}
});
} else {
Toast.makeText(this, "No File Selected", Toast.LENGTH_SHORT).show();
}
}
private void openImagesActivity()
{
Intent intent = new Intent(Gallery.this,ImagesActivity.class);
startActivity(intent);
}
}
This below one is the ImagesActivity which is for the recyclerview, here the delete operation works, as I mentioned and I have used the AlertDialog to open and update the details I tried to Mimic some things from gallery.java but was not able to figure out how they should be Arranged.
public class ImagesActivity extends AppCompatActivity implements ImageAdapter.OnItemClickListener {
private RecyclerView mRecyclerView;
private ImageAdapter mAdapter;
private ProgressBar mProgressCircle;
private static final int PICK_IMAGE_REQUEST= 1;
private StorageTask mUploadTask;
private Uri mImageUri;
private StorageReference mStorageRef;
private FirebaseStorage mStorage;
private DatabaseReference mDatabaseRef;
private ValueEventListener mDBListener;
private List<UploadImage> mUploads;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_images);
mRecyclerView = findViewById(R.id.recycler_view);
mProgressCircle= findViewById(R.id.progress_circle);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mUploads = new ArrayList<>();
mAdapter = new ImageAdapter(ImagesActivity.this,mUploads);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(ImagesActivity.this);
mStorage = FirebaseStorage.getInstance();
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
mDBListener = mDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mUploads.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()){
UploadImage uploadImage = postSnapshot.getValue(UploadImage.class);
uploadImage.setKey(postSnapshot.getKey());
mUploads.add(uploadImage);
}
mAdapter.notifyDataSetChanged();
mProgressCircle.setVisibility(View.INVISIBLE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(ImagesActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
mProgressCircle.setVisibility(View.INVISIBLE);
}
});
}
private String getFileExtension(Uri uri)
{
ContentResolver cR = getContentResolver();
MimeTypeMap mime = MimeTypeMap.getSingleton();
return mime.getExtensionFromMimeType(cR.getType(uri));
}
#Override
public void onItemClick(int position) {
Toast.makeText(this, "Normal Click", Toast.LENGTH_SHORT).show();
}
#Override
public void onUpdateClick(int position) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.update_dialog, null);
dialogBuilder.setView(dialogView);
final EditText TextName = (EditText) dialogView.findViewById(R.id.txtName);
final EditText TextDesc = (EditText) dialogView.findViewById(R.id.txtDesc);
final ImageView ImageView = (ImageView) dialogView.findViewById(R.id.imgView);
final Button chooseFile = (Button) dialogView.findViewById(R.id.btnChoose);
final Button UpdateDetails = (Button) dialogView.findViewById(R.id.btnUpdate);
dialogBuilder.setTitle("Update Details");
final AlertDialog b = dialogBuilder.create();
b.show();
chooseFile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openFileChooser();
}
});
UpdateDetails.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mUploadTask != null && mUploadTask.isInProgress())
{
Toast.makeText(ImagesActivity.this, "Upload In Progress", Toast.LENGTH_SHORT).show();
}
else
{
if (mImageUri != null)
{
StorageReference fileReference = mStorageRef.child(System.currentTimeMillis()
+ "." + getFileExtension(mImageUri));
mUploadTask = fileReference.putFile(mImageUri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(ImagesActivity.this, "Update Successful", Toast.LENGTH_LONG).show();
UploadImage uploadImage = new UploadImage(TextName.getText().toString().trim(),
TextDesc.getText().toString().trim(),taskSnapshot.getDownloadUrl().toString());
String uploadId = mDatabaseRef.push().getKey();
mDatabaseRef.setValue(uploadImage);
mDatabaseRef.child(uploadId).setValue(uploadImage);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(ImagesActivity.this,e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} else {
Toast.makeText(ImagesActivity.this, "No File Selected", Toast.LENGTH_SHORT).show();
}
}
b.dismiss();
}
});
UploadImage selectedItem = mUploads.get(position);
final String selectedKey = selectedItem.getKey();
// Toast.makeText(this, "Update Clicked", Toast.LENGTH_SHORT).show();
}
private void openFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,PICK_IMAGE_REQUEST);
}
#Override
public void onDeleteClick(int position) {
UploadImage selectedItem = mUploads.get(position);
final String selectedKey = selectedItem.getKey();
StorageReference imageRef = mStorage.getReferenceFromUrl(selectedItem.getImageUrl());
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
mDatabaseRef.child(selectedKey).removeValue();
Toast.makeText(ImagesActivity.this, "Item Deleted", Toast.LENGTH_SHORT).show();
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
mDatabaseRef.removeEventListener(mDBListener);
}
}
This below one is for set and get methods named as UploadImage.java
public class UploadImage {
private String mName;
private String mDesc;
private String mImageUrl;
private String mKey;
public UploadImage()
{
//Empty Constructor Needed
}
public UploadImage(String name, String desc, String imageUrl)
{
if (name.trim().equals(""))
{
name = "No Name";
desc = "No Description";
}
mName = name;
mDesc = desc;
mImageUrl = imageUrl;
}
public String getName() {
return mName;
}
public void setName(String name) {
mName = name;
}
public String getDesc() {
return mDesc;
}
public void setDesc(String desc) {
mDesc=desc;
}
public String getImageUrl() {
return mImageUrl;
}
public void setImageUrl(String imageUrl) {
mImageUrl=imageUrl;
}
#Exclude
public String getKey(){
return mKey;
}
#Exclude
public void setKey(String key){
mKey = key;
}
}
The following one for the Adapter
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
private Context mContext;
private List<UploadImage> mUploads;
private OnItemClickListener mListener;
public ImageAdapter(Context context, List<UploadImage> uploads){
mContext = context;
mUploads = uploads;
}
#Override
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.image_item,parent,false);
return new ImageViewHolder(v);
}
#Override
public void onBindViewHolder(ImageViewHolder holder, int position) {
UploadImage uploadImageCurrent = mUploads.get(position);
holder.textViewName.setText(uploadImageCurrent.getName());
Picasso.with(mContext)
.load(uploadImageCurrent.getImageUrl())
.placeholder(R.drawable.ic_image_black_24dp)
.fit()
.centerCrop()
.into(holder.imageView);
}
#Override
public int getItemCount() {
return mUploads.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener{
public TextView textViewName;
public ImageView imageView;
public ImageViewHolder(View itemView) {
super(itemView);
textViewName = itemView.findViewById(R.id.text_view_name);
imageView = itemView.findViewById(R.id.image_view_upload);
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
}
#Override
public void onClick(View v) {
if (mListener != null)
{
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION){
//To Handle Normal Item Clicks
mListener.onItemClick(position);
}
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Select Action");
MenuItem Update = menu.add(Menu.NONE, 1, 1, "Update");
MenuItem Delete = menu.add(Menu.NONE, 2, 2, "Delete");
Update.setOnMenuItemClickListener(this);
Delete.setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
if (mListener != null)
{
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION){
//To Check Which Menu Item Was Clicked
switch (item.getItemId())
{
case 1:
mListener.onUpdateClick(position);
return true;
case 2:
mListener.onDeleteClick(position);
return true;
}
}
}
return false;
}
}
public interface OnItemClickListener{
void onItemClick(int position);
void onUpdateClick(int position);
void onDeleteClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
}
Any Solution for this how can I update it.
There is no update method in firebase storage, So for a workaround:
get the name the file you want to delete
delete the file you want to update
upload the new file
rename file with the previous file name