Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

displaying firebase storage images in a RecyclerView

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());
                    }
                });
}
like image 874
hozdaman Avatar asked Sep 14 '16 21:09

hozdaman


People also ask

How do I show data from Firebase to RecyclerView?

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.


2 Answers

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.

like image 105
Francisco Durdin Garcia Avatar answered Oct 16 '22 12:10

Francisco Durdin Garcia


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

    }
like image 37
ugur Avatar answered Oct 16 '22 13:10

ugur