Hi I asked an earlier question about displaying an image using Base64 from my Firebase database. It was recommended to use firebase storage. I reworked my code and everything loads into the firebase storage and databse as it should. The issue I have is when I save the data nothing populates into my recyclerview. Everything is blank.
Any help you can provide me to get this to work would be great. Thanks.
EDIT: In my activity class I am calling a button clicklistener to activate the camera. Once the picture is taken it is saved to Firebase Storage. Then I download it the image from Storage and display it in a recyclerview. I understand the uploading portion but I am having difficulty understanding the downloading and displaying portion. Thanks.
viewholder:bind method
public void bind (ImageProgress progress){
Glide.with(activity).load("").into(image);
}
}
adapter
@Override
public ProgressViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
return new ProgressViewHolder(activity, activity.getLayoutInflater().inflate(R.layout.weight_progress_list, parent, false));
main activity class
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.weight_progress);
saveButton = (Button) findViewById(R.id.saveButton);
progressStatusEditText = (EditText) findViewById(R.id.progressStatusEditText);
progressList = (RecyclerView) findViewById(R.id.progressList);
mImageButton = (ImageButton) findViewById(R.id.takePictureButton);
capturedImage=(ImageView)findViewById(R.id.capturedImageView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
progressList.setHasFixedSize(false);
progressList.setLayoutManager(layoutManager);
//take picture button
mImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openCamera();
}
});
mDatabaseReference = database.getReference("Progress");
saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//get current user
FirebaseUser user =FirebaseAuth.getInstance().getCurrentUser();
String uid = user.getUid();
ImageProgress progress = new ImageProgress(uid, progressStatusEditText.getText().toString());
mDatabaseReference.push().setValue(progress);
progressStatusEditText.setText("");
}
});
}
private void openCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Uri cameraImageURI = data.getData();
//reference where images will be stored
mStorageReference = storage.getReference("Progress Images");
//reference to store file
final StorageReference cameraImageRef = mStorageReference.child(cameraImageURI.getLastPathSegment());
//upload to firebase storage
cameraImageRef.putFile(cameraImageURI)
.addOnSuccessListener(this, new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
progressStatusEditText.setText(downloadUrl.toString());
}
});
}
Step 1: Open Android Studio and create a new project named “RecyclerView” with an empty activity. Step 2: Connect your Firebase project with your app. Step 3: Add the following dependency in your app/build. gradle file in order to get the FirebaseUI and Firebase Realtime Database support in the app.
I suggest you add setImage method on your RecyclerView.ViewHolder
and store the url of your image in the object that you retrieve in your FirebaseRecyclerAdapter
.
In my case, I'm using a Glide to manage the images of my app:
My ViewHolder Example:
public class UserListViewHolder extends RecyclerView.ViewHolder {
private final View mView;
private static final int POST_TEXT_MAX_LINES = 6;
private ImageView mIconView;
private TextView mAuthorView;
private UserClickListener mListener;
public UserListViewHolder(View itemView) {
super(itemView);
mView = itemView;
mIconView = (ImageView) mView.findViewById(R.id.user_image_profile);
mAuthorView = (TextView) mView.findViewById(R.id.user_text_profile);
mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onUserClick();
}
});
}
public void setIcon(String url) {
GlideUtil.loadProfileIcon(url, mIconView);//
}
public void setPostClickListener(UserClickListener listener) {
mListener = listener;
}
public void setText(final String text) {
if (text == null || text.isEmpty()) {
mAuthorView.setVisibility(View.GONE);
return;
} else {
mAuthorView.setVisibility(View.VISIBLE);
mAuthorView.setText(text);
mAuthorView.setMaxLines(POST_TEXT_MAX_LINES);
}
}
public interface UserClickListener {
void onUserClick();
}
}
And here is my database call:
private FirebaseRecyclerAdapter<Person, UserListViewHolder> getFirebaseRecyclerAdapter(Query query) {
return new FirebaseRecyclerAdapter<Person, UserListViewHolder>(
Person.class, R.layout.user_row_item, UserListViewHolder.class, query) {
@Override
protected void populateViewHolder(UserListViewHolder viewHolder, Person model, int position) {
setupUser(viewHolder, model, position, null);
}
};
}
private void setupUser(final UserListViewHolder UserViewHolder, final Person user, final int position, final String inPostKey) {
final String postKey;
if (mAdapter instanceof FirebaseRecyclerAdapter) {
postKey = ((FirebaseRecyclerAdapter) mAdapter).getRef(position).getKey();
} else {
postKey = inPostKey;
}
FirebaseUtil.getUsersRef().child(postKey).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(final DataSnapshot dataSnapshot) {
UserViewHolder.setPostClickListener(new UserListViewHolder.UserClickListener() {
@Override
public void onUserClick() {
mGroup.addUserToGroup(dataSnapshot.getKey());
}
});
UserViewHolder.setIcon(dataSnapshot.child("photoUrl").getValue(String.class));
UserViewHolder.setText(dataSnapshot.child("displayName").getValue(String.class));
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
You just need to set the image in the same way that you set your others values when retrieving data from Firebase, but using your already generated newURL for that image after upload it to the cloud.
Maybe you can find another way to just set the url, but I suggest you to keep it like another parameter in your custom object, being dynamic if you want to retrieve that data more than once even if you are not uploading the image.
There is already an official implementation for this purpose.
https://github.com/firebase/quickstart-android/tree/master/storage
The basic idea is to upload the image to the firebase storage and the store the image url to the database and then download it via this link.
In the MyDownloadService.java class mStorageRef.child(downloadPath).getStream method was used but i implemented with getBytes method not to deal with inputstreams. Because can load bytes with Glide easily. When the task is completed, it sends a broadcast intent with bytes as bundle. You can listen the broadcast receiver wherever u want in order to load ur image when it is downloaded.
public class DownloadService extends Service{
private StorageReference mStorageRef;
@Override
public void onCreate() {
super.onCreate();
// Initialize Storage
mStorageRef = FirebaseStorage.getInstance().getReference();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (ACTION_DOWNLOAD.equals(intent.getAction())) {
mStorage.child(downloadPath).getBytes(10*1024*1024).addOnSuccessListener(new OnSuccessListener<byte[]>() {
@Override
public void onSuccess(byte[] bytes) {
Log.d(TAG, "download:SUCCESS " + bytes.length);
// Send success broadcast with number of bytes downloaded
Intent broadcast = new Intent(ACTION_COMPLETED);
broadcast.putExtra(EXTRA_DOWNLOAD_BYTES, bytes);
broadcast.putExtra(EXTRA_DOWNLOAD_INDEX, uid);
LocalBroadcastManager.getInstance(getApplicationContext())
.sendBroadcast(broadcast);
// Mark task completed
taskCompleted();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
Log.w(TAG, "download:FAILURE", exception);
// Send failure broadcast
Intent broadcast = new Intent(ACTION_ERROR);
broadcast.putExtra(EXTRA_DOWNLOAD_PATH, downloadPath);
LocalBroadcastManager.getInstance(getApplicationContext())
.sendBroadcast(broadcast);
// Mark task completed
taskCompleted();
}
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With