Getting Photos From Firebase Storage based on UID - android

I'm facing an issue.
I'm getting photos through UID,
but issue is in firebase database where images are replacing
if I use the push then application didn't get images from firebase
Firebase Database Image
If I remove push from database then images will be show, but as you can see that images will overlap everytime user upload image
Here is my code for onActivityResult
#Override
protected void onActivityResult ( int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
final FirebaseUser currentFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK) {
TitleName=title.getText().toString();
progressDialog.setMessage("Uploading .....");
progressDialog.show();
Uri uri = data.getData();
StorageReference filePath = storageReference.child("Photos").child(currentFirebaseUser.getUid()).child(uri.getLastPathSegment());
filePath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadPath = taskSnapshot.getDownloadUrl();
Glide.with(MainActivity.this).load(downloadPath).centerCrop().into(imageView);
Toast.makeText(getApplicationContext(), "DONE" + TitleName, Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
//creating the upload object to store uploaded image details
Upload upload = new Upload(taskSnapshot.getDownloadUrl().toString(), TitleName);
//adding an upload to firebase database
// String uploadId = mDatabase.push().getKey();
mDatabase.child(currentFirebaseUser.getUid())***.push().***setValue(upload);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
If i remove push from
mDatabase.child(currentFirebaseUser.getUid())***.push().***setValue(upload);
then images will be show on recyclerView.
Any suggestions?
ShowImagesActivity
public class ShowImagesActivity extends AppCompatActivity {
//recyclerview object
private RecyclerView recyclerView;
//adapter object
private RecyclerView.Adapter adapter;
//database reference
private DatabaseReference mDatabase;
//progress dialog
private ProgressDialog progressDialog;
//list to hold all the uploaded images
private List<Upload> uploads;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recycler_view);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
progressDialog = new ProgressDialog(this);
uploads = new ArrayList<>();
//displaying progress dialog while fetching images
progressDialog.setMessage("Loading your memories ...");
progressDialog.show();
mDatabase = FirebaseDatabase.getInstance().getReference(Constants.DATABASE_PATH_UPLOADS);
//adding an event listener to fetch values
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
//dismissing the progress dialog
progressDialog.dismiss();
//iterating through all the values in database
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Upload upload = postSnapshot.getValue(Upload.class);
uploads.add(upload);
}
//creating adapter
adapter = new MyAdapter(getApplicationContext(), uploads);
//adding adapter to recyclerview
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
}
Constants.java
public static final String DATABASE_PATH_UPLOADS = "uploads";
public static final String STORAGE_PATH_UPLOADS = "uploads/";
Adapter.java
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private Context context;
private List<Upload> uploads;
public MyAdapter(Context context, List<Upload> uploads) {
this.uploads = uploads;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_images, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Upload upload = uploads.get(position);
holder.textViewName.setText(upload.getName());
Glide.with(context).load(upload.getUrl()).into(holder.imageView);
}
#Override
public int getItemCount() {
return uploads.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewName;
public ImageView imageView;
public ViewHolder(View itemView) {
super(itemView);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
}
}
}
upload.java
public class Upload{
public String name;
public String url;
// Default constructor required for calls to
// DataSnapshot.getValue(User.class)
public Upload() {
}
public Upload( String url, String name) {
this.name = name;
this.url= url;
}
public String getName() {
return name;
}
public String getUrl() {
return url;
}

Related

Images are not being shown in recyclerview

I'm trying to make an app where users are able to signup for an account and they can upload images. I got the uploading part down pack but I want to retrieve those images to the user on their profile page but I don't know how to. Can someone show me how I can retrieve those images I want to use a recycler view for this. Thanks in advance. Below is my code
// Upload Image class
public class UploadImageActivity extends AppCompatActivity implements View.OnClickListener {
int PICK_IMAGE_REQUEST=234;
private Button upload,button2;
private ImageView imageView;
private Uri filepath;
FirebaseAuth firebaseAuth;
FirebaseUser firebaseUser;
FirebaseDatabase firebaseDatabase;
TextView next;
FirebaseStorage firebaseStorage;
StorageReference storageReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload_ad);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
firebaseStorage=FirebaseStorage.getInstance();
storageReference=firebaseStorage.getReference();
next=findViewById(R.id.next0);
firebaseUser= firebaseAuth.getInstance().getCurrentUser();
firebaseDatabase.getInstance().getReference();
upload=findViewById(R.id.button_upload);
button2=findViewById(R.id.submit);
imageView=findViewById(R.id.view_image);
upload.setOnClickListener(this);
}
private void showFileChooser(){
Intent intent=new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Choose an image"),PICK_IMAGE_REQUEST);
}
#Override
protected 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){
next.setTextColor(Color.parseColor("#FF4500"));
next.setEnabled(true);
filepath=data.getData();
try {
// Bitmap bitmap=new Compressor(this).setMaxHeight(200) //Set height and width
// .setMaxWidth(200)
//.setQuality(100) // Set Quality
//.compressToBitmap(file);
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),filepath);
imageView.setImageBitmap(bitmap);
// build alert dialog
} catch (IOException e) {
e.printStackTrace();
}
}
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(filepath != null) {
final ProgressDialog progressDialog=new ProgressDialog(UploadAdActivity.this);
progressDialog.setTitle("Uploading");
progressDialog.show();
int aNumber = (int) (20 * Math.random()) + 1;
//StorageReference riversRef=storageReference.child(firebaseUser.getUid()+"/"+"image.png");
// StorageReference=firebaseStorage.getInstance().getReferenceFromUrl()
StorageReference riversRef = storageReference.child(System.currentTimeMillis()+"."+getExtension(filepath));
//final String url=riversRef.getDownloadUrl().getResult().toString();
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("Users");
final DatabaseReference update = rootRef.child(uid).child("images");
riversRef.putFile(filepath).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
Toast.makeText(UploadAdActivity.this,"Uploaded successfully",Toast.LENGTH_LONG).show();
storageReference.getDownloadUrl();
taskSnapshot.getStorage().getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String download_url=uri.toString();
update.child("images").setValue(download_url);
}
});
}
}).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(#NonNull UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot
.getTotalByteCount());
progressDialog.setMessage("Uploaded "+(int)progress+"%"); }
});
}
}
});
}
private String getExtension(Uri filepath) {
ContentResolver contentResolver=getContentResolver();
MimeTypeMap mimeTypeMap=MimeTypeMap.getSingleton();
return mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(filepath));
};
#Override
public void onClick(View v) {
if(v==upload){
showFileChooser();
//uploadImage();
next.setTextColor(Color.parseColor("#FF4500"));
/*
Intent i = new Intent(UploadAdActivity.this, ActionActivity.class);
//i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
*/
}
}
}
//Users profile
public class ProfileActivity extends AppCompatActivity implements View.OnClickListener {
private RecyclerView recyclerView;
private ImageAdapter mAdapter;
private DatabaseReference databaseReference;
private List<Upload> mUploads;
FirebaseAuth firebaseAuth;
FirebaseUser firebaseUser;
int PICK_IMAGE_REQUEST=234;
private Button upload,button2;
private ImageView imageView;
private Uri filepath;
FirebaseDatabase firebaseDatabase;
FirebaseStorage firebaseStorage;
StorageReference storageReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
overridePendingTransition(R.anim.slide_right, R.anim.slide_left);
mUploads=new ArrayList<>();
mAdapter=new ImageAdapter(ProfileActivity.this, mUploads);
recyclerView=findViewById(R.id.recyclerView);
//recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(mAdapter);
firebaseStorage=FirebaseStorage.getInstance();
storageReference=firebaseStorage.getReference();
firebaseUser= firebaseAuth.getInstance().getCurrentUser();
firebaseDatabase.getInstance().getReference();
upload=findViewById(R.id.button_upload);
button2=findViewById(R.id.submit);
imageView=findViewById(R.id.view_image);
upload.setOnClickListener(this);
String uid=FirebaseAuth.getInstance().getCurrentUser().getUid();
databaseReference=FirebaseDatabase.getInstance().getReference();
//databaseReference.child("images");
databaseReference.orderByChild(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(ProfileActivity.this,databaseError.getMessage(),Toast.LENGTH_LONG).show();
}
});
recyclerView.setAdapter(mAdapter); //Again set adapter to recyclerview
}
//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);
Picasso.get().load(uploadCurrent.getmImageUrl()).fit().centerCrop().into(holder.imageView);
}
#Override
public int getItemCount() {
return mUploads.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder{
public ImageView imageView;
public ImageViewHolder(#NonNull View itemView) {
super(itemView);
imageView=itemView.findViewById(R.id.imageview);
}
}
}
//Upload class
public class Upload {
private String images;
public Upload(){
//Empty constructor needed
}
public Upload (String imageUrl){
images=imageUrl;
}
public String getmImageUrl() {
return images;
}
public void setmImageUrl(String images) {
this.images = images;
}
}
Put recyclerView.setAdapter(mAdapter);
after
databaseReference.orderByChild(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(ProfileActivity.this,databaseError.getMessage(),Toast.LENGTH_LONG).show();
}
});
create a refresh function in adaptor
public void refresh(List<Upload> uploads){
this.uploads=uploads;
notifyDataSetChanged();
}
call this where you get the data from server or firebase using adaptor like this
mAdapter.refresh(mUploads);

Firestore Recycler adapter - images from firestore

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)
}

Images don't appear in RecyclerView using Firebase-UI, Firestore as database and Picasso

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

Android RecyclerView duplicating images from Firebase

I'm writing a small group chat application in Android Studio and using Firebase as the backend. I'm trying to allow the users to post images however everytime I send an image to firebase storage and retrieve it in order to post into a recycler view using Glide, it duplicates in the recycler view. I've confirmed the image in the firebase storage is NOT duplicating, it's just on the recycler view on the app itself. I've been struggling with this issue for days and cannot for the life of me find why it's duplicating.
Here's my code:
Uploads and Retrieves the image URL in Firebase
public void uploadImage(final Uri filePath) {
if (filePath != null) {
final String pathToImage = "chatImages/" + user.getUid()+"/"+ UUID.randomUUID();
StorageReference storeRef = storageReference.child(pathToImage);
UploadTask uploadTask = storeRef.putFile(filePath);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "Upload Failed");
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Log.e(TAG, "Upload Successful");
//now that the image has been uploaded, send to chat
storageReference.child(pathToImage).getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
//adds photo, username and message to the arraylists\
imagePath = uri.toString();
Log.e(TAG, "done");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "Failed to Retrieve Image Message");
}
});
}
});
}
}
Adds the image and other post info to the recycler view
db.collection("chats").document("0fv4XvLpi8dWivyohQbk").collection("chatMessages")
.orderBy("TimeStamp")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot queryDocumentSnapshots, #Nullable FirebaseFirestoreException e) {
if (e != null) {
Log.e(TAG, "Listen Failed", e);
return;
}
//temporay arraylists
final ArrayList<String> uIdAL = new ArrayList<>();
//gets any updates
for (DocumentChange newdoc : queryDocumentSnapshots.getDocumentChanges()) {
if (newdoc.getType() == DocumentChange.Type.ADDED) {
Log.e(TAG, "new message" + newdoc.getDocument().getData());
//saves userIDs for later use in getting profile pics
uIdAL.add((String) newdoc.getDocument().getData().get("userID"));
//temporary profile picture
if(chatPhotoUrl != null && ((String) newdoc.getDocument().getData().get("userID")).equals(user.getUid()))
{
messageAvatars.add(chatPhotoUrl.toString());
}
else
{
messageAvatars.add("https://pictures.digitalrev.com/image/upload/v1454493563/gzev2fhfpoizg3bpozjr.jpg");
}
//get usernames and messages
userNames.add((String) newdoc.getDocument().getData().get("userName"));
messages.add((String) newdoc.getDocument().getData().get("message"));
imageMessages.add((String) newdoc.getDocument().getData().get("imageMessage"));
//add to recycler view
adapter.notifyItemInserted(userNames.size());
rv.scrollToPosition(userNames.size() - 1);
Log.e(TAG, "here");
}
}
}
});
}
Recycler View Adapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
private static final String TAG = "RecyclerViewAdapter";
private ArrayList<String> messageAvatars = new ArrayList<>();
private ArrayList<String> userNames = new ArrayList<>();
private ArrayList<String> messages = new ArrayList<>();
private ArrayList<String> imageMessages = new ArrayList<>();
private Context context;
public RecyclerViewAdapter(ArrayList<String> messageAvatars, ArrayList<String> userNames, ArrayList<String> messages, ArrayList<String> imageMessages, Context context) {
this.messageAvatars = messageAvatars;
this.userNames = userNames;
this.messages = messages;
this.imageMessages = imageMessages;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerviewitem,parent, false);
ViewHolder viewholder = new ViewHolder(view);
return viewholder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Log.e(TAG, "onBindViewHolder: called");
//sets the fields in the recyclerview item
Glide.with(context).asBitmap().load(messageAvatars.get(position)).into(holder.messageImage);
holder.userName.setText(userNames.get(position));
holder.messageText.setText(messages.get(position));
Glide.with(context).asBitmap().load(imageMessages.get(position)).into(holder.imageMessage);
//triggers if the recyclerview item is clicked
holder.parentLayout.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view)
{
Log.e(TAG, "onClick: clicked");
}
});
}
#Override
public int getItemCount() {
return userNames.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public class ViewHolder extends RecyclerView.ViewHolder{
CircleImageView messageImage;
TextView userName;
TextView messageText;
ImageView imageMessage;
ConstraintLayout parentLayout;
public ViewHolder(View itemView) {
super(itemView);
messageImage = itemView.findViewById(R.id.chatImageView);
userName = itemView.findViewById(R.id.usernametextView);
messageText = itemView.findViewById(R.id.messagetextView);
imageMessage = itemView.findViewById(R.id.imageView);
parentLayout = itemView.findViewById(R.id.parentlayout);
}
}
Any and all help would be appreciated!

Share Image intent File not supported

I'm facing issue in image intent when I click share button for share image it says file doesn't support.
Here is my code:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private Context context;
private List<Upload> uploads;
Upload upload;
public MyAdapter(Context context, List<Upload> uploads) {
this.uploads = uploads;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_images, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
upload = uploads.get(position);
holder.textViewName.setText(upload.getName());
Glide.with(context).load(upload.getUrl()).into(holder.imageView);
}
#Override
public int getItemCount() {
return uploads.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewName;
public ImageView imageView,shareImage;
public ViewHolder(View itemView) {
super(itemView);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
imageView = (ImageView) itemView.findViewById(R.id.imageView);
shareImage=(ImageView)itemView.findViewById(R.id.share);
shareImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(upload.getUrl()));
shareIntent.setType("image/*");
context.startActivity(Intent.createChooser(shareIntent, "Share your memoir via:"));
}
});
}
}
}
Here is my showImageActivity.java
public class ShowImagesActivity extends Activity {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private DatabaseReference mDatabase;
private ProgressDialog progressDialog;
//list to hold all the uploaded images
private List<Upload> uploads;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recycler_view);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
progressDialog = new ProgressDialog(this);
final FirebaseUser currentFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
uploads = new ArrayList<>();
//displaying progress dialog while fetching images
progressDialog.setMessage("Loading your memories ...");
progressDialog.show();
mDatabase = FirebaseDatabase.getInstance().getReference(Constants.DATABASE_PATH_UPLOADS);
//adding an event listener to fetch values
mDatabase.child(currentFirebaseUser.getUid()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
//dismissing the progress dialog
progressDialog.dismiss();
//iterating through all the values in database
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Upload upload = postSnapshot.getValue(Upload.class);
uploads.add(upload);
}
//creating adapter
adapter = new MyAdapter(ShowImagesActivity.this, uploads);
//adding adapter to recyclerview
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
}
I'm using firebase. In upload.getUrl image url is saved on firebase Database while image actually saved in firebase Storage.
Here I'm storing images
final FirebaseUser currentFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
TitleName=title.getText().toString();
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK) {
progressDialog.setMessage("Uploading .....");
progressDialog.show();
Uri uri = data.getData();
StorageReference filePath = storageReference.child(Constants.STORAGE_PATH_UPLOADS).child(currentFirebaseUser.getUid()).child(uri.getLastPathSegment());
filePath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadPath = taskSnapshot.getDownloadUrl();
Glide.with(MainActivity.this).load(downloadPath).fitCenter().into(imageView);
Toast.makeText(getApplicationContext(), "Memory Uploaded", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
//creating the upload object to store uploaded image details
Upload upload = new Upload(taskSnapshot.getDownloadUrl().toString(), TitleName);
//adding an upload to firebase database
String uploadId = mDatabase.push().getKey();
mDatabase.child(currentFirebaseUser.getUid()).child(uploadId).setValue(upload);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
You need to save your image before sharing it. There's a sample code for saving imageview's drawing cache and sharing it. Hope it helps.
Just edit your code like this:
shareImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
share(imageview);
}
});
public Bitmap capture(View view) {
view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
return bitmap;
}
public void share(View view) {
Context context = view.getContext();
Bitmap bitmap = capture(view);
try {
File file = new File(context.getExternalCacheDir(), DateUtil.format(new Date(), "yyyyMMdd_HHmm") + ".png");
FileOutputStream fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("image/png");
Uri uri = Uri.fromFile(file);
i.putExtra(Intent.EXTRA_STREAM, uri);
context.startActivity(Intent.createChooser(i, "Share"));
} catch (IOException e) {
e.printStackTrace();
}
}

Categories

Resources