JS07
JS07

Reputation: 33

Firebase Realtime Database not displaying images in Recyclerview

I am new at Android and I am making an app that displays the user's uploaded images of clothes. I can upload the pictures perfectly but for some reason I cannot display the images from firebase realtime database into the RecyclerView. I have been searching for a solution for weeks.

Please help me out. Thank you so much for your time.

TopActivity.java

public class TopActivity extends AppCompatActivity {
    FloatingActionButton fab;

    //Uploading Images to Firebase
    private static final int PICK_IMAGE = 1;
    private Uri ImageUri;
    ArrayList ImageList = new ArrayList();
    private int upload_count = 0;
    private ProgressDialog progressDialog;
    ArrayList urlStrings;
    List<String> imagesEncodedList;
    Uri uri,mImageUri;
    String imageEncoded;
    ArrayList<Uri> mArrayUri = new ArrayList<>();
    RecyclerView recyclerView;
    DatabaseReference databaseReference,dbreference;
    private ArrayList<Tops> topslist;
    private TopsAdapter topsAdapter;
    private Context mContext;
    StorageReference ImageFolder,Folder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_top);

        fab = findViewById(R.id.fab);
        recyclerView=findViewById(R.id.recyclerView);
        GridLayoutManager gridLayoutManager=new GridLayoutManager(TopActivity.this,2);
        recyclerView.setLayoutManager(gridLayoutManager);
        recyclerView.setHasFixedSize(true);

        topslist = new ArrayList<>();
        GetDataFromFirebase();

        progressDialog = new ProgressDialog(TopActivity.this);
        progressDialog.setMessage("Uploading Images Please Wait");
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                intent.setType("image/*");
                intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                startActivityForResult(intent,PICK_IMAGE);
            }
        });
    }

    private void uploadImage(){
        urlStrings = new ArrayList<>();
        progressDialog.show();
         ImageFolder = FirebaseStorage.getInstance().getReference().child("Tops");

        for (upload_count = 0; upload_count < mArrayUri.size(); upload_count++) {

            Uri IndividualImage = (Uri) mArrayUri.get(upload_count);
            final StorageReference ImageName = ImageFolder.child("Top_" + IndividualImage.getLastPathSegment());

            ImageName.putFile(IndividualImage).addOnSuccessListener(
                    new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            ImageName.getDownloadUrl().addOnSuccessListener(
                                    new OnSuccessListener<Uri>() {
                                        @Override
                                        public void onSuccess(Uri uri) {
                                            urlStrings.add(String.valueOf(uri));



                                            if (urlStrings.size() == mArrayUri.size()) {
                                                storeLink(urlStrings);
                                            }

                                        }
                                    }
                            );
                        }
                    }
            );
        }
    }

    private void storeLink(ArrayList<String> urlStrings) {
        HashMap<String,String > hashMap = new HashMap<>();

        for (int i = 0; i <urlStrings.size() ; i++) {
            hashMap.put("Top "+i, urlStrings.get(i));
        }

        databaseReference = FirebaseDatabase.getInstance().getReference("TopsFolder");

        databaseReference.push().setValue(hashMap)
                .addOnCompleteListener(
                        new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                if (task.isSuccessful()) {
                                    Toast.makeText(TopActivity.this, "Successfully Uploaded", Toast.LENGTH_SHORT).show();
                                }
                            }
                        }
                ).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(TopActivity.this, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
        progressDialog.dismiss();

        ImageList.clear();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        try {

            if (requestCode == PICK_IMAGE && resultCode == RESULT_OK
                    && null != data) {
                imagesEncodedList = new ArrayList<String>();
                String[] filePathColumn = {MediaStore.Images.Media.DATA};

                if (data.getData() != null) {
                     mImageUri = data.getData();

                    // Get the cursor
                    Cursor cursor = getContentResolver().query(mImageUri,
                            filePathColumn, null, null, null);
                    // Move to first row
                    cursor.moveToFirst();

                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                    imageEncoded = cursor.getString(columnIndex);
                    cursor.close();

                    uploadImage();
                } else {
                    if (data.getClipData() != null) {

                        ClipData mClipData = data.getClipData();
                        for (int i = 0; i < mClipData.getItemCount(); i++) {
                            ClipData.Item item = mClipData.getItemAt(i);
                            uri = item.getUri();
                            mArrayUri.add(uri);

                            // Get the cursor
                            Cursor cursor = getContentResolver().query(uri, filePathColumn, null, null, null);
                            // Move to first row
                            cursor.moveToFirst();

                            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                            imageEncoded = cursor.getString(columnIndex);
                            imagesEncodedList.add(imageEncoded);
                            cursor.close();

                        }
                        Log.v("LOG_TAG", "Selected Images" + mArrayUri.size());

                        uploadImage();
                    }
                }

            } else {
                Toast.makeText(this, "You haven't picked Image",
                        Toast.LENGTH_LONG).show();
            }
        } catch (Exception e) {
            Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
                    .show();
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

private void GetDataFromFirebase(){

    //Query query=databaseReference.child("TopsFolder/Tops");
    //query.addValueEventListener(new ValueEventListener() {
    databaseReference = FirebaseDatabase.getInstance().getReference();
    dbreference=databaseReference.child("TopsFolder");
    ValueEventListener eventListener = new ValueEventListener() {

        @Override
        public void onDataChange( DataSnapshot dataSnapshot) {
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                Tops tops=ds.child("TopsFolder").getValue(Tops.class);
                topslist.add(tops);
            }

            topsAdapter= new TopsAdapter(getApplicationContext(),topslist);
            recyclerView.setAdapter(topsAdapter);
            topsAdapter.notifyDataSetChanged();
        }


        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    };
    dbreference.addListenerForSingleValueEvent(eventListener);
}
}

TopsAdapter.java

public class TopsAdapter extends RecyclerView.Adapter<TopsAdapter.ViewHolder> {

private  static  final String Tag="RecyclerView";
private Context mContext;
private ArrayList<Tops> topslist;

    public TopsAdapter(Context mContext, ArrayList<Tops> topslist) {
        this.mContext = mContext;
        this.topslist = topslist;
    }

    @NonNull
    @Override
    public TopsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext())
                .inflate(R.layout.top_rv_item,parent,false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Glide.with(mContext)
                .load(topslist.get(position).getTop())
                .into(holder.ivTopGallery);
    }

    @Override
    public int getItemCount() {
        return topslist.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
    ImageView ivTopGallery;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);

        ivTopGallery=itemView.findViewById(R.id.ivTopGallery);
    }
}
}

Tops.java

public class Tops {

    //Model Class

   public String top;

    //Constructors
    public Tops(){}

    public Tops(String top) {
        this.top = top;
    }

    public String getTop() {
        return top;
    }

    public void setTop(String top) {
        this.top = top;
    }
}

top_rv_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
        android:layout_height="150dp"
        android:layout_width="150dp"
        android:padding="10dp"
        android:id="@+id/ivTopGallery"
        android:scaleType="fitXY"
        />

</LinearLayout>

Here's my database structure.

enter image description here

Update so I changed my code to fit the data structure

Firebase-root
   |
   --- TopsFolder
         |
         --- pushedId
         |     |
         |     --- top: "https://..."
         |
         --- pushedId
               |
               --- top: "https://..."

Here is the change I made in my TopsActivity.java

private void storeLink(ArrayList<String> urlStrings) {

        HashMap<String, String> hashMap = new HashMap<>();
        databaseReference = FirebaseDatabase.getInstance().getReference("TopsFolder");
        for (int i = 1; i <urlStrings.size() ; i++) {

           hashMap.put("Top "+i, urlStrings.get(i));
            databaseReference.push().setValue(hashMap);
        }

        progressDialog.dismiss();
        Toast.makeText(TopActivity.this, "Successfully Uploaded", Toast.LENGTH_SHORT).show();

        ImageList.clear();
    }

put now I am getting this as my data structure. What do I do to get it in the format mentioned above? enter image description here

Upvotes: 3

Views: 161

Answers (3)

Alex Mamo
Alex Mamo

Reputation: 138824

You cannot map the objects that exist under the TopsFolder node into objects of type Tops because none of those objects actually represents an object of type Tops. However, if you need to map each object into a Tops object, you need to restructure your schema like so:

Firebase-root
   |
   --- TopsFolder
         |
         --- pushedId
         |     |
         |     --- top: "https://..."
         |
         --- pushedId
               |
               --- top: "https://..."

In this way, each object under TopsFolder represents a Tops object. See, the name of the property is "top", as in your Tops class, and the "value" is the actual URL. The code required should look like this:

@Override
public void onDataChange( DataSnapshot dataSnapshot) {
    for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String url = ds.getValue(String.class);
            if (topList != null) toplist.clear(); // Clear the list if there's anything already in the list 
            topslist.add(url);
    }
    topsAdapter= new TopsAdapter(getApplicationContext(), topslist);
    recyclerView.setAdapter(topsAdapter);
    topsAdapter.notifyDataSetChanged();
}

Edit:

Tops tops = new Tops("https://...");
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference topFolderRef = rootRef.child("TopsFolder");
topFolderRef.push().setValue(tops);

Please also don't forget to make the top property private in your Tops class.

Upvotes: 0

Reaz Murshed
Reaz Murshed

Reputation: 24211

Your database actually stores a list of String under TopsFolder node and you need to get those as a list of strings. Hence I would recommend changing your onDataChange implementation inside GetDataFromFirebase function as follows.

@Override
public void onDataChange( DataSnapshot dataSnapshot) {
    for(DataSnapshot ds : dataSnapshot.getChildren()) {
            // You should have the elements as an array of string. 
            Tops[] tops = ds.child("TopsFolder").getValue(Tops[].class);
            if (topList != null) toplist.clear(); // Clear the list if there's anything already in the list 
            topslist = Arrays.asList(tops);  // Assign the items to the list from the array that you retrieved from firebase database.
    }

    topsAdapter= new TopsAdapter(getApplicationContext(), topslist);
    recyclerView.setAdapter(topsAdapter);
    topsAdapter.notifyDataSetChanged();
}

That should solve your problem.

Upvotes: 1

Alex Escobar
Alex Escobar

Reputation: 96

you can use Picasso Library implementation 'com.squareup.picasso:picasso:2.5.2' this works for me.

public static void setUrlImageInView(Context context, String url, ImageView view) {
    // (optional) use Picasso to download and show to image
    Picasso.with(context).load(url).into(view);

}

Another thing to consider is that you are getting data from the same child again. You must use Id of document in your example case

Tops tops=ds.child("-MIPf9A2H_.....").getValue(Tops.class);
topslist.add(tops);

Upvotes: 0

Related Questions