I am trying to retrieve images from Firebase Firestore. I am able to retrieve text in RecyclerView successfully however I'm not sure how to retrieve the images.
I had a look at similar questions unfortunately none helped.
My MainClass
package com.harsh.preacher.ui.HomeToDestination;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import com.google.firebase.firestore.DocumentChange;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.QuerySnapshot;
import com.harsh.preacher.R;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class MustHaveEquipment extends AppCompatActivity {
DocumentSnapshot documentSnapshot;
RecyclerView recyclerView;
ArrayList<ProductModel> productModelArrayList ;
ProductAdapter productAdapter;
FirebaseFirestore db;
ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_must_have_equipment);
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setMessage("Loading Products");
progressDialog.show();
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
db = FirebaseFirestore.getInstance();
productModelArrayList = new ArrayList<ProductModel>();
productAdapter = new ProductAdapter(MustHaveEquipment.this,productModelArrayList);
recyclerView.setAdapter(productAdapter);
EventChangeListner();
}
private void EventChangeListner() {
db.collection("Products")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable #org.jetbrains.annotations.Nullable QuerySnapshot value, #Nullable #org.jetbrains.annotations.Nullable FirebaseFirestoreException error) {
if(error!=null){
if(progressDialog.isShowing())
progressDialog.dismiss();
Log.e("No Internet Connection",error.getMessage());
}
for (DocumentChange dc : value.getDocumentChanges()){
if(dc.getType() == DocumentChange.Type.ADDED){
productModelArrayList.add(dc.getDocument().toObject(ProductModel.class));
}
productAdapter.notifyDataSetChanged();
if(progressDialog.isShowing())
progressDialog.dismiss();
}
}
});
}
}
My Adapter Class
package com.harsh.preacher.ui.HomeToDestination;
import android.content.Context;
import android.os.Build;
import android.transition.AutoTransition;
import android.transition.TransitionManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.FirebaseAppLifecycleListener;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.harsh.preacher.R;
import com.squareup.picasso.Picasso;
import org.jetbrains.annotations.NotNull;
import org.w3c.dom.Document;
import java.util.ArrayList;
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
DocumentSnapshot documentSnapshot;
Context context;
ArrayList<ProductModel> productModelArrayList;
public ProductAdapter(Context context, ArrayList<ProductModel> productModelArrayList) {
this.context = context;
this.productModelArrayList = productModelArrayList;
}
#NonNull
#NotNull
#Override
public ProductAdapter.ProductViewHolder onCreateViewHolder(#NonNull #NotNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.epupiment_design,parent,false);
return new ProductViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull #NotNull ProductAdapter.ProductViewHolder holder, int position) {
ProductModel productModel = productModelArrayList.get(position);
holder.productName.setText(productModel.ProductName);
holder.aboutProduct.setText(productModel.AboutProduct);
holder.productDescription.setText(productModel.ProductUse);
}
#Override
public int getItemCount() {
return productModelArrayList.size();
}
public static class ProductViewHolder extends RecyclerView.ViewHolder {
TextView aboutProduct,productName,productDescription;
RelativeLayout expandable,card;
ImageView showmore,productImage;
public ProductViewHolder(#NonNull #NotNull View itemView) {
super(itemView);
aboutProduct = itemView.findViewById(R.id.productDescription);
productName = itemView.findViewById(R.id.productName);
productDescription = itemView.findViewById(R.id.aboutProduct);
productImage = itemView.findViewById(R.id.productImage);
expandable = itemView.findViewById(R.id.expandable);
card = itemView.findViewById(R.id.cardeshwar);
showmore = itemView.findViewById(R.id.showMore);
showmore.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public void onClick(View view) {
if (expandable.getVisibility() == View.VISIBLE) {
TransitionManager.beginDelayedTransition(card,
new AutoTransition());
expandable.setVisibility(View.GONE);
showmore.setImageResource(R.drawable.showmore);
} else {
TransitionManager.beginDelayedTransition(card,
new AutoTransition());
expandable.setVisibility(View.VISIBLE);
showmore.setImageResource(R.drawable.showless);
}
}
});
}
}
}
My model class
package com.harsh.preacher.ui.HomeToDestination;
import android.widget.ImageView;
public class ProductModel {
String ProductName, ProductUse, AboutProduct;
ImageView ProductImage;
public ProductModel(){}
public ProductModel(String productName, String productUse, String aboutProduct,ImageView productImage){
ProductName = productName;
ProductUse = productUse;
AboutProduct = aboutProduct;
ProductImage = productImage;
}
public String getProductName() {
return ProductName;
}
public void setProductName(String productName) {
ProductName = productName;
}
public String getProductUse() {
return ProductUse;
}
public void setProductUse(String productUse) {
ProductUse = productUse;
}
public String getAboutProduct() {
return AboutProduct;
}
public void setAboutProduct(String aboutProduct) {
AboutProduct = aboutProduct;
}
public ImageView getProductImage() {
return ProductImage;
}
public void setProductImage(ImageView productImage) {
ProductImage = productImage;
}
}
Here is the structure of my database
Follow these steps to show images in RecyclerView
Remove ImageView from ProductModel
Add String imageUrl to ProductModel and set its value with the image URL from Firestore (I see from the screenshot that it is named "Image").
In onBindViewHolder from the ProductAdapter, use the position provided to retrieve the appropriate ProductModel from productModelArrayList and pass its imageUrl value to ProductViewHolder.
In ProductViewHolder, use the imageUrl to load the image into the ImageView. (Glide and Picasso are two commonly used library to load images)
PS: Never add UI elements in your model. It will cause lifecycle issues in the future.
Let me know if you have any questions.
Related
I want to get data from my Firebase Fire store database. I have a collection called categories. I am beginner in Android and would really appreciate it if someone could please help me. Here is my code.
MainActivity.java:
package com.example.kuizapp;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setMessage("Loding..");
progressDialog.show();
FirebaseFirestore database = FirebaseFirestore.getInstance();
RecyclerView recyclerView = findViewById(R.id.categoryList);
ArrayList<CategoryModel> categories = new ArrayList<>();
CategoryAdapter adapter = new CategoryAdapter(this, categories);
database.collection("categories")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot value, #Nullable
FirebaseFirestoreException error) {
categories.clear();
if(error!=null){
if(progressDialog.isShowing())
progressDialog.dismiss();
Log.d("fireStore Error", error.getMessage());
return;
}
for (DocumentSnapshot snapshot : value.getDocuments()) {
CategoryModel model = snapshot.toObject(CategoryModel.class);
model.setCategoryId(snapshot.getId());
categories.add(model);
}
adapter.notifyDataSetChanged();
if(progressDialog.isShowing())
progressDialog.dismiss();
}
});
GridLayoutManager layoutManager = new GridLayoutManager(this, 2); //`2 spanCount`
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
}
CategoryModel.java:
package com.example.kuizapp;
public class CategoryModel {
private String categoryId, categoryName, categoryImage;
public CategoryModel(String categoryId, String categoryName, String categoryImage) {
this.categoryId = categoryId;
this.categoryName = categoryName;
this.categoryImage = categoryImage;
}
public String getCategoryId() {
return categoryId;
}
public void setCategoryId(String categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getCategoryImage() {
return categoryImage;
}
public void setCategoryImage(String categoryImage) {
this.categoryImage = categoryImage;
}
}
CategoryAdapter:
`
package com.example.kuizapp;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.CategoryViewHolder> {
Context context;
ArrayList<CategoryModel> categoryModels;
public CategoryAdapter(Context context, ArrayList<CategoryModel> categoryModels){
this.context = context;
this.categoryModels = categoryModels;
}
#NonNull
#NotNull
#Override
public CategoryViewHolder onCreateViewHolder(#NonNull #NotNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_category,parent,false);
return new CategoryViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull #NotNull CategoryViewHolder holder, int position) {
CategoryModel model = categoryModels.get(position);
holder.textView.setText(categoryModels.get(position).getCategoryName());
}
#Override
public int getItemCount() {
return categoryModels.size();
}
public static class CategoryViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
TextView textView;
public CategoryViewHolder(#NonNull #NotNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.image);
textView = itemView.findViewById(R.id.category);
}
}
}
`
I am trying to get the position of the item in a recycler view in order to pass it down to other activities, but after actually managing to get the item id, I found out that I'm getting a -1, therefore not getting a correct id there. What could be causing this?
The activity:
package com.gmproxy.pastilarma;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.SearchView;
import android.widget.Toast;
import androidx.recyclerview.*;
import com.gmproxy.Adapters.PathologyListAdapter;
import com.gmproxy.Adapters.PathologyViewHolder;
import com.gmproxy.DAO.PathologyDAO;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.Util.PathologyViewModel;
public class PathologiesSearchScreen extends AppCompatActivity {
private PathologyViewModel viewModel;
SearchView searchView;
RecyclerView recyclerView;
private PathologyDAO pathDao;
private Pathology pathology;
private PathologyViewHolder holder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pathology_search_list);
searchView = findViewById(R.id.SearchView);
recyclerView = findViewById(R.id.recyclerview);
final PathologyListAdapter adapter = new PathologyListAdapter(new PathologyListAdapter.UserDiff());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
viewModel = new ViewModelProvider(this).get(PathologyViewModel.class);
viewModel.pathologies.observe(this, adapter::submitList);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
viewModel.setFilter(searchView.getQuery().toString());
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
long start;
start = System.currentTimeMillis();
if ((newText.length() > 3) && (System.currentTimeMillis() - start > 500)) {
viewModel.setFilter(searchView.getQuery().toString());
}
return false;
}
});
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(#NonNull #org.jetbrains.annotations.NotNull RecyclerView rv, #NonNull #org.jetbrains.annotations.NotNull MotionEvent e) {
pathology = getSelectedPathology(findViewById(R.id.recyclerview));
Log.println(Log.INFO, "PathologyTest", pathology.toString());
final CharSequence[] options = {"Si", "No"};
AlertDialog.Builder builder = new AlertDialog.Builder(PathologiesSearchScreen.this);
builder.setTitle("¿Añadir la patología " + pathology.getPathologyName() + "?");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (options[item].equals("Si")) {
Toast.makeText(PathologiesSearchScreen.this, "Has añadido la patología " + pathology.getPathologyName() + ".", Toast.LENGTH_SHORT).show();
Intent mainAct = new Intent(PathologiesSearchScreen.this, UserAddScreen.class);
mainAct.putExtra("path", pathology);
} else if (options[item].equals("No")) {
dialog.dismiss();
}
}
});
builder.show();
return true;
}
#Override
public void onTouchEvent(#NonNull #org.jetbrains.annotations.NotNull RecyclerView rv, #NonNull #org.jetbrains.annotations.NotNull MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
});
}
public Pathology getSelectedPathology(View v){
holder = new PathologyViewHolder(v);
long idlongo = recyclerView.getAdapter().getItemId(holder.getAdapterPosition());
Log.println(Log.INFO, "PathologyTest", String.valueOf(idlongo));
int id = (int) idlongo;
Pathology path = pathDao.findObjectbyId(id);
return path;
}
}
The view holder:
package com.gmproxy.Adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import com.gmproxy.DAO.PathologyDAO;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.pastilarma.PathologiesSearchScreen;
import com.gmproxy.pastilarma.R;
import java.nio.file.Path;
public class PathologyViewHolder extends RecyclerView.ViewHolder {
public final TextView objItemView;
public PathologyViewHolder(View itemView) {
super(itemView);
objItemView = itemView.findViewById(R.id.textView);
}
public void bind(String text) {
objItemView.setText(text);
}
static PathologyViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.pathologies_item, parent, false);
return new PathologyViewHolder(view);
}
}
The list adapter:
package com.gmproxy.Adapters;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.pastilarma.PathologiesSearchScreen;
import com.gmproxy.pastilarma.UserAddScreen;
public class PathologyListAdapter extends ListAdapter<Pathology, PathologyViewHolder> {
public PathologyListAdapter(#NonNull DiffUtil.ItemCallback<Pathology> diffCallback) {
super(diffCallback);
}
#Override
public PathologyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return PathologyViewHolder.create(parent);
}
#Override
public void onBindViewHolder(PathologyViewHolder holder, int position) {
Pathology current = getItem(position);
holder.bind(current.getPathologyName());
}
public static class UserDiff extends DiffUtil.ItemCallback<Pathology> {
#Override
public boolean areItemsTheSame(#NonNull Pathology oldItem, #NonNull Pathology newItem) {
return oldItem == newItem;
}
#Override
public boolean areContentsTheSame(#NonNull Pathology oldItem, #NonNull Pathology newItem) {
return oldItem.getPathologyName().equals(newItem.getPathologyName());
}
}
}
The entity DAO:
package com.gmproxy.DAO;
import androidx.lifecycle.LiveData;
import androidx.room.*;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.Entities.User;
import java.util.List;
#Dao
public interface PathologyDAO {
#Query("SELECT * FROM condiciones")
LiveData<List<Pathology>> getAllObjects();
//This will come in handy for getting all those pathologies, will need to get them on a for loop since I'm not completely sure
//that the query will handle int[]
#Query("SELECT id_condiciones FROM condiciones WHERE id_condiciones LIKE :id_condiciones")
int getPathologiesForUser(int id_condiciones);
#Query("SELECT nombreCondicion FROM condiciones WHERE nombreCondicion LIKE :pathologyName")
String getPathologiesForName(String pathologyName);
#Query("SELECT * FROM condiciones WHERE nombreCondicion LIKE :pathologyName")
Pathology getPathologiesCompleteForName(String pathologyName);
#Query("SELECT * FROM condiciones WHERE id_condiciones = :id")
Pathology findObjectbyId(int id);
#Query("SELECT * FROM condiciones WHERE nombreCondicion LIKE '%' || :filter || '%'")
LiveData<List<Pathology>> filterText(String filter);
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAllObjects(List<Pathology> listObjects);
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insertObject(Pathology object);
#Update
void updateObject(Pathology object);
#Delete
void delete(Pathology obj);
}
The entity repository:
package com.gmproxy.DAO;
import android.app.Application;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import com.gmproxy.Entities.Pathology;
import com.gmproxy.Entities.User;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class PathologyRepository {
private PathologyDAO concerningDao;
private LiveData<List<Pathology>> pathologyList;
public PathologyRepository(Application application) {
DatabaseHelper db = DatabaseHelper.getDatabase(application);
concerningDao = db.pathologyDao();
pathologyList = concerningDao.getAllObjects();
}
public LiveData<List<Pathology>> getAllObjects() {
return concerningDao.getAllObjects();
}
void insertAllObjects(List<Pathology> objectsList) {
DatabaseHelper.databaseWriteExecutor.execute(() ->{
concerningDao.insertAllObjects(objectsList);
});
}
public void insertObject(Pathology obj){
DatabaseHelper.databaseWriteExecutor.execute(() ->{
concerningDao.insertObject(obj);
});
}
public void deleteObject(Pathology obj) {
concerningDao.delete(obj);
}
public LiveData<List<Pathology>> filter(String input){
try{
return new FilterNoteAsyncTask(concerningDao).execute(input).get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
private static class FilterNoteAsyncTask extends AsyncTask<String, Void, LiveData<List<Pathology>>> {
private PathologyDAO pathologyDAO;
private FilterNoteAsyncTask(PathologyDAO pathologyDAO) {
this.pathologyDAO = pathologyDAO;
}
#Override
protected LiveData<List<Pathology>> doInBackground(String... strings) {
return pathologyDAO.filterText(strings[0]);
}
}
}
Move your PathologyListAdapter to global, and get adapter position using adapter object instead of getting adapter from recyclerview.
public Pathology getSelectedPathology(){
long idlongo = adapter.getAdapterPosition();
Log.println(Log.INFO, "PathologyTest", String.valueOf(idlongo));
int id = (int) idlongo;
Pathology path = pathDao.findObjectbyId(id);
return path;
}
I'm getting an error E/RecyclerView: No adapter attached; skipping layout while using FirestoreRecylerAdapter INSIDE a FRAGMENT. After reading all answers to similar questions ,I'm not able to reach to a solution because most of them are for recylerAdapter inside activiy, i.e. they have an onCreate method where they can set up their adapter first. In fragments as you know,there is no view in onCreate method so I can't find my recyclerView there.Some answers are suggesting to setup an empty adapter and then notify for data change.
I'm not able to able to setup an empty adapter in onCreateView. Here's my code:
My adapter:
package com.example.XX;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
public class ProfileRecyclerAdapter extends FirestoreRecyclerAdapter<Profile,ProfileRecyclerAdapter.ProfileViewHolder> {
public ProfileRecyclerAdapter(#NonNull FirestoreRecyclerOptions<Profile> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull ProfileViewHolder holder, int position, #NonNull Profile profile) {
holder.Name_textView.setText(profile.getName());
holder.Sector_textView.setText(profile.getSector());
holder.Pincode_textView.setText(profile.getPincode());
}
#NonNull
#Override
public ProfileViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
View view=layoutInflater.inflate(R.layout.profile_row_item,parent,false);
return new ProfileViewHolder(view);
}
class ProfileViewHolder extends RecyclerView.ViewHolder{
TextView Name_textView;
TextView Sector_textView;
TextView Pincode_textView;
public ProfileViewHolder(#NonNull View itemView) {
super(itemView);
Name_textView=itemView.findViewById(R.id.Name_textView);
Sector_textView=itemView.findViewById(R.id.Sector_textView);
Pincode_textView=itemView.findViewById(R.id.Pincode_textView);
}
}
}
My FRAGMENT where I want the data to be displayed:
package com.example.XX;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.List;
public class MainQueryFragment extends Fragment {
RecyclerView recyclerView;
ProfileRecyclerAdapter profileRecyclerAdapter;
TextView yourSector;
TextView yourPincode;
FirebaseFirestore db = FirebaseFirestore.getInstance();
String tuserID = FirebaseAuth.getInstance().getCurrentUser().getUid();
String customerPincode;
String customerSector;
String sectorText;
String pincodeText;
String[] testArray;
String name;
String pincode;
String address;
String mobileNumber;
String sector;
String avgDeliveryTime;
String avgDeliveryTimeUrg;
Boolean item1;
Boolean item2;
Boolean item3;
Boolean item4;
Boolean item5;
Boolean item6;
Boolean item7;
Boolean item8;
Boolean item9;
Boolean item10;
String speciality;
String avgNumOrders;
String shopType;
String userID;
String avgPriceRange;
String education;
Button button;
public MainQueryFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_main_query, container, false);
yourSector = view.findViewById(R.id.Sector_tv);
yourPincode = view.findViewById(R.id.Pincode_tv);
recyclerView = view.findViewById(R.id.recyclerView_Profile);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(profileRecyclerAdapter);
{ DocumentReference docRef = db.collection("customerUsers").document(tuserID);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
customerPincode = document.getString("pincode");
customerSector = document.getString("sector");
sectorText = "Sector : " + customerSector;
pincodeText = "Pincode : " + customerPincode;
yourSector.setText(sectorText);
yourPincode.setText(pincodeText);
Log.d("work", "onComplete: " + customerPincode);
} else {
Log.d("docref", "No such document");
}
} else {
Log.d("docref", "get failed with ", task.getException());
}
}
});
}//doc for sector,pincode loading
if (getArguments() != null) {
MainQueryFragmentArgs args = MainQueryFragmentArgs.fromBundle(getArguments());
testArray = args.getArrayCheckboxData();
}
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
button=view.findViewById(R.id.startQuery_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Query query = FirebaseFirestore.getInstance()
.collection("tUsers")
.whereEqualTo("pincode", customerPincode)
.whereEqualTo("sector", customerSector)
.whereEqualTo(testArray[0], true)
.whereEqualTo(testArray[1], true)
.whereEqualTo(testArray[2], true)
.whereEqualTo(testArray[3], true);
FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
.setQuery(query,Profile.class)
.build();
profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
recyclerView.setAdapter(profileRecyclerAdapter);
profileRecyclerAdapter.startListening();
}
});
}
}
Even if I comment out my button and onclicklistener and then run the app,I should be technically running an empty adapter. Still I'm getting the same error.
Please suggest what i should do,keeping in mind I CANNOT use onCreate
Edit Here is my edited code. Now I'm getting null Pointer exception and my app is crashing:
package com.example.XX;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.List;
public class MainQueryFragment extends Fragment {
RecyclerView recyclerView;
ProfileRecyclerAdapter profileRecyclerAdapter;
TextView yourSector;
TextView yourPincode;
FirebaseFirestore db = FirebaseFirestore.getInstance();
String tuserID = FirebaseAuth.getInstance().getCurrentUser().getUid();
String customerPincode;
String customerSector;
String sectorText;
String pincodeText;
String[] testArray;
String name;
String pincode;
String address;
String mobileNumber;
String sector;
String avgDeliveryTime;
String avgDeliveryTimeUrg;
Boolean item1;
Boolean item2;
Boolean item3;
Boolean item4;
Boolean item5;
Boolean item6;
Boolean item7;
Boolean item8;
Boolean item9;
Boolean item10;
String speciality;
String avgNumOrders;
String shopType;
String userID;
String avgPriceRange;
String education;
Button button;
public MainQueryFragment() {
// Required empty public constructor
}
#Override
public void onStart() {
super.onStart();
profileRecyclerAdapter.startListening();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_main_query, container, false);
yourSector = view.findViewById(R.id.Sector_tv);
yourPincode = view.findViewById(R.id.Pincode_tv);
{ DocumentReference docRef = db.collection("customerUsers").document(tuserID);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
customerPincode = document.getString("pincode");
customerSector = document.getString("sector");
sectorText = "Sector : " + customerSector;
pincodeText = "Pincode : " + customerPincode;
yourSector.setText(sectorText);
yourPincode.setText(pincodeText);
Log.d("work", "onComplete: " + customerPincode);
} else {
Log.d("docref", "No such document");
}
} else {
Log.d("docref", "get failed with ", task.getException());
}
}
});
}//doc for sector,pincode loading
if (getArguments() != null) {
MainQueryFragmentArgs args = MainQueryFragmentArgs.fromBundle(getArguments());
testArray = args.getArrayCheckboxData();
}
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
button=view.findViewById(R.id.startQuery_button);
recyclerView = view.findViewById(R.id.recyclerView_Profile);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Query query = FirebaseFirestore.getInstance()
.collection("tUsers")
.whereEqualTo("pincode", customerPincode)
.whereEqualTo("sector", customerSector)
.whereEqualTo(testArray[0], true)
.whereEqualTo(testArray[1], true)
.whereEqualTo(testArray[2], true)
.whereEqualTo(testArray[3], true);
FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
.setQuery(query,Profile.class)
.build();
profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
recyclerView.setAdapter(profileRecyclerAdapter);
pailorProfileRecyclerAdapter.notifyDataSetChanged();
}
});
}
#Override
public void onStop() {
super.onStop();
profileRecyclerAdapter.stopListening();
}
}
When you first create your Adapter in onCreateView(), you are not initializing that adapter, instead, you are setting the adapter right from the property:
ProfileRecyclerAdapter profileRecyclerAdapter;
recyclerView.setAdapter(profileRecyclerAdapter);
You need to initialize your adapter to set that adapter to your RecyclerView.
Second, you should not have that asynchronous call inside your onCreateView(), instead, use onViewCreated() to handle your asynchronous calls after your view is created.
Then, you are also making your adapter instance in your onViewCreated() with:
FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
.setQuery(query,Profile.class)
.build();
profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
recyclerView.setAdapter(profileRecyclerAdapter);
profileRecyclerAdapter.startListening();
And you should do:
profileRecyclerAdapter.startListening();
In your onStart() and profileRecyclerAdapter.stopListening(); at your onStop()
Instead of using adapter.startListening and
adapter.stopListening use .setLifecycleOwner(this)
Check out this working code:
FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
.setQuery(query,Profile.class)
.setLifecycleOwner(this)
.build();
profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
recyclerView.setAdapter(profileRecyclerAdapter)
I am working on this blog app with firebase in backend but it is not retrieving image. Actually it is not showing up images neither the profile image nor the blog image. I have pasted the code of the app help me in retrieving the image.Thanks in advance.
'''package com.example.theblog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.example.theblog.BlogPost;
import com.example.theblog.R;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import java.sql.Date;
import java.text.DateFormat;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
public class BlogRecyclerAdapter extends RecyclerView.Adapter<BlogRecyclerAdapter.ViewHolder> {
public List<BlogPost> blog_list;
public Context context;
private FirebaseFirestore firebaseFirestore;
public FirebaseAuth firebaseAuth;
public BlogRecyclerAdapter(List<BlogPost> blog_list){
this.blog_list=blog_list;
}
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.blog_list_item,parent,false);
context=parent.getContext();
firebaseAuth=FirebaseAuth.getInstance();
firebaseFirestore=FirebaseFirestore.getInstance();
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, int position) {
holder.setIsRecyclable(false);
String desc_data=blog_list.get(position).getDesc();
holder.setDescText(desc_data);
String imageUrl=blog_list.get(position).getImage_url();
holder.setBlogImage(imageUrl);
try{
long millisecond=blog_list.get(position).getTimestamp().getTime();
android.text.format.DateFormat df = new android.text.format.DateFormat();
String dateString=df.format("dd/MM/yyyy ", new Date(millisecond)).toString();
holder.setDate(dateString);
}catch (Exception e){
Toast.makeText(context,"Exception"+e.getMessage(),Toast.LENGTH_LONG).show();
}
String user_id=blog_list.get(position).getUser_id();
firebaseFirestore.collection("Users").document(user_id).get().addOnCompleteListener(
new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()){
String userName=task.getResult().getString("name");
String userImage=task.getResult().getString("image");
holder.setUserData(userName,userImage);
}else {
String error=task.getException().getMessage();
Toast.makeText(context,"Error"+error,Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public int getItemCount() {
return blog_list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private View mView;
private TextView descView;
private TextView blogDate;
private CircleImageView blogUserImage;
private ImageView blogImage;
private TextView blogUserName;
public ViewHolder(View itemView) {
super(itemView);
mView=itemView;
}
public void setDescText(String descText){
descView=mView.findViewById(R.id.blog_post_desc);
descView.setText(descText);
}
public void setDate(String date){
blogDate=mView.findViewById(R.id.blog_date);
blogDate.setText(date);
}
public void setUserData(String userName,String userImage){
blogUserName=mView.findViewById(R.id.blog_user_name);
blogUserName.setText(userName);
blogUserImage=mView.findViewById(R.id.blog_user_image);
RequestOptions request=new RequestOptions();
request.placeholder(R.color.grayColor);
Glide.with(context).applyDefaultRequestOptions(request).load(userImage).into(blogUserImage);
}
public void setBlogImage(String downloadUri){
blogImage=mView.findViewById(R.id.blog_image);
RequestOptions requestOptions=new RequestOptions();
requestOptions.placeholder(R.color.grayColor);
Glide.with(context).load(downloadUri).into(blogImage);
}
}
}
'''
The code for BlogPost is given below.
'''
package com.example.theblog;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FieldValue;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import com.theartofdev.edmodo.cropper.CropImage;
import com.theartofdev.edmodo.cropper.CropImageView;
import java.util.HashMap;
import java.util.Map;
import de.hdodenhof.circleimageview.CircleImageView;
public class PostActivity extends AppCompatActivity {
private ImageView newPostImage;
private EditText newPostDesc;
private FloatingActionButton newPostBtn;
private Uri postImageUri=null;
private StorageReference storageReference;
private FirebaseFirestore firebaseFirestore;
private FirebaseAuth firebaseAuth;
private ProgressBar progressBar;
private String current_user_id;
private static final int GalleryPick =1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post);
setTitle("Post Blog");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
storageReference= FirebaseStorage.getInstance().getReference();
firebaseAuth=FirebaseAuth.getInstance();
firebaseFirestore=FirebaseFirestore.getInstance();
current_user_id=firebaseAuth.getCurrentUser().getUid();
newPostImage=findViewById(R.id.image);
newPostBtn=findViewById(R.id.btn);
newPostDesc=findViewById(R.id.desc);
progressBar=findViewById(R.id.progress1);
newPostImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CropImage.activity()
.setGuidelines(CropImageView.Guidelines.ON)
.setAspectRatio(1,1)
.start(PostActivity.this);
}
});
newPostBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String desc=newPostDesc.getText().toString();
if (!TextUtils.isEmpty(desc) && postImageUri!=null){
String randomName= FieldValue.serverTimestamp().toString();
progressBar.setVisibility(View.VISIBLE);
StorageReference filepath=storageReference.child("post Images").child(randomName+".jpg");
filepath.putFile(postImageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()){
Task<Uri> downloadUri=task.getResult().getMetadata().getReference().getDownloadUrl();
Map<String,Object> postMap=new HashMap<>();
postMap.put("image_url",downloadUri.toString());
postMap.put("user_id",current_user_id);
postMap.put("desc",desc);
postMap.put("timestamp",FieldValue.serverTimestamp());
firebaseFirestore.collection("Posts").add(postMap).addOnCompleteListener(new OnCompleteListener<DocumentReference>() {
#Override
public void onComplete(#NonNull Task<DocumentReference> task) {
if (task.isSuccessful()){
Toast.makeText(PostActivity.this,"Your Post is Uploaded",Toast.LENGTH_LONG).show();
Intent mainIntent=new Intent(PostActivity.this,MainActivity.class);
startActivity(mainIntent);
}else {
String error =task.getException().getMessage();
Toast.makeText(PostActivity.this,"Error"+error,Toast.LENGTH_LONG).show();
progressBar.setVisibility(View.INVISIBLE);
}
}
});
}else {
String error =task.getException().getMessage();
Toast.makeText(PostActivity.this,"Error"+error,Toast.LENGTH_LONG).show();
progressBar.setVisibility(View.INVISIBLE);
}
}
});
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE){
CropImage.ActivityResult result =CropImage.getActivityResult(data);
if (resultCode==RESULT_OK){
postImageUri=result.getUri();
newPostImage.setImageURI(postImageUri);}
else if (resultCode==CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE){
Exception error = result.getError();
}
}
}
}
'''
Please help my finding the solution for this problem and thanks in advance.
package com.novela.minha.novela;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.client.Firebase;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyHolder> {
Context c;
ArrayList<Beaches> beaches;
private long itemId;
private Firebase firebase;
Firebase likeRef;
FirebaseAuth user;
public com.firebase.client.Firebase Ref ;
private DatabaseReference Database = FirebaseDatabase.getInstance().getReference();
private DatabaseReference mDatabaseLike = FirebaseDatabase.getInstance().getReference().child("Likes");
private boolean mProcessLike = false;
public MyAdapter(Context c, ArrayList<Beaches> beaches){
this.c= c;
this.beaches=beaches;
}
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.card,parent,false);
final MyHolder holder= new MyHolder(v);
return holder;
}
#Override
public void onBindViewHolder(final MyHolder holder, final int position) {
final String post_key = Database.getRef(position).getKey().toString(); // <- Error
mDatabaseLike.keepSynced(true);
holder.nameTxt.setText(beaches.get(position).getName());
holder.textoTxt.setText(beaches.get(position).getTexto());
holder.siteTxt.setText(beaches.get(position).getSite());
holder.emissoraTxt.setText(beaches.get(position).getEmissora());
holder.enderecoTxt.setText(beaches.get(position).getEndereco());
PicassoClient.downloadimg(c, beaches.get(position).getUrl(),holder.img);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String url = beaches.get(position).getEndereco().toString();
Intent intent = new Intent( v.getContext().getApplicationContext(), Web.class);
intent.putExtra("VALOR", url);
v.getContext().getApplicationContext().startActivity(intent);
}
});
holder.like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
Toast.makeText(v.getContext(), post_key, Toast.LENGTH_SHORT).show();
mProcessLike = true ;
if (mProcessLike) {
mDatabaseLike.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
});
}
#Override
public int getItemCount() {
return beaches.size();
}
}
Note that getRef does not accept position,
returns an error, which could be done in the code, I already searched here in the Forum but I did not find a solution, thank you ,Note that getRef does not accept position,
returns an error, which could be done in the code, I already searched here in the Forum
but I did not find a solution, I'm new to programming, thank you
final String post_key = Database.push().getKey();