The data is being fetched in the fetchData() method in FirebaseHelper, but isn't actually being stored in the variables petInfo and imgURL in the CardViewAdapter. This results in no cards showing in the RecyclerView fragment. When the app initializes, the dataset is 0, runs through the fetchData and the dataset is the size of items but leaves petInfo and imgURL null.
FirebaseHelper:
public class FirebaseHelper {
private DatabaseReference mDatabase;
Boolean saved = null;
ArrayList<AnimalType> animal = new ArrayList<>();
public FirebaseHelper(DatabaseReference mDatabase) {
this.mDatabase = mDatabase;
}
//Save
public Boolean save (AnimalType animalType){
if (animalType==null){
saved = false;
}
else{
try{
mDatabase.child("AnimalType").push().setValue(animalType);
saved=true;
}catch (DatabaseException e){
e.printStackTrace();
saved=false;
}
}
return saved;
}
//Read
public ArrayList<AnimalType> retrieve(){
mDatabase.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
Log.i(TAG, "onChildAdded");
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
Log.i(TAG, "onChildChanged");
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return animal;
}
private void fetchData (DataSnapshot dataSnapshot){
animal.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()){
AnimalType animalType = new AnimalType();
animalType.setPetInfo(ds.getValue(AnimalType.class).getPetInfo());
animalType.setImgURL(ds.getValue(AnimalType.class).getImgURL());
animal.add(animalType);
}
}
}
Adapter:
public class CardViewAdapter extends RecyclerView.Adapter<CardViewAdapter.ViewHolder> {
Context mContext;
private List<AnimalType> mAnimalData = new ArrayList<>();
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView petInfo;
public ImageView imgURL;
public ViewHolder(View view){
super(view);
imgURL = (ImageView) view.findViewById(R.id.pet_image);
petInfo = (TextView) view.findViewById(R.id.pet_description);
}
}
//constructor
public CardViewAdapter(Context mContext, List<AnimalType> mAnimalData){
this.mAnimalData = mAnimalData;
}
//create new views
#Override
public CardViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
ViewHolder viewHolder = new ViewHolder(itemView);
mContext = parent.getContext();
return viewHolder;
}
//replace contents of view
#Override
public void onBindViewHolder(ViewHolder holder, int position){
holder.petInfo.setText(mAnimalData.get(position).getPetInfo());
PicassoClient.downloadImage(mContext,mAnimalData.get(position).getImgURL(), holder.imgURL);
}
//return size of dataset
public int getItemCount(){
return mAnimalData.size();
}
}
Fragment:
public class DogFragment extends Fragment {
public static final String ARG_PAGE = "ARG_PAGE";
private int mPage;
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mCardAdapter;
private RecyclerView.LayoutManager mCardLayoutManager;
DatabaseReference mDatabaseReference;
FirebaseHelper helper;
public static DogFragment newInstance(int page) {
DogFragment dogFragment = new DogFragment();
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
dogFragment.setArguments(args);
return dogFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPage = getArguments().getInt(ARG_PAGE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_dog, container, false);
//cardview
mRecyclerView = (RecyclerView)rootView.findViewById(R.id.card_view);
//setup firebase
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
helper= new FirebaseHelper(mDatabaseReference);
//create adapter class
//mCardAdapter = new CardViewAdapter(mAimalTypeList);
mCardAdapter = new CardViewAdapter(getActivity().getApplicationContext(), helper.retrieve());
mRecyclerView.setAdapter(mCardAdapter);
//add linear layout manager
mCardLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mCardLayoutManager);
//preparePetData();
return rootView;
}
}
Picasso:
public class PicassoClient {
public static void downloadImage(Context context, String url, ImageView img){
if(url != null && url.length()>0){
Picasso.with(context).load(url).placeholder(R.drawable.placeholder).into(img);
}
else {
Picasso.with(context).load(R.drawable.placeholder).into(img);
}
}
}
Your call to helper.retrieve() is kicking off mDatabase.addChildEventListener the results of which will come back asynchronously....in the meantime you're returning empty list from that method (default value of animal). You need to update adapter when results come back (after you've called fetchData(dataSnapshot);)
Related
Please see the following issue:
All User Profile Images are not successfully displaying in the RecyclerView.
Text view is successfully displaying in the RecyclerView.
I looked up other similar issues online, but have not been able to find a solution.
I have updated my google play services, and my Firebase storage dependencies.
I am able to successfully pull the current user profile image in another activity.
I am getting the following 404 error message below:
**Adapter**
public class FindFriendsAdapter extends RecyclerView.Adapter<FindFriendsAdapter.FindFriendsViewHolder>
{
private Context context;
private List<FindFriendModel> findFriendModelList;
////This is a constructor and is a must have for recyclerviews/////
public FindFriendsAdapter(Context context, List<FindFriendModel> findFriendModelList) {
this.context = context;
this.findFriendModelList = findFriendModelList;
}
////This is a constructor and is a must have for recyclerviews/////
#NonNull
#Override
public FindFriendsAdapter.FindFriendsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.find_friends_layout, parent, false);
return new FindFriendsViewHolder(view); ///// layout converts our xml layout file to a programmable file some kind of way.
}
#Override
public void onBindViewHolder(#NonNull FindFriendsAdapter.FindFriendsViewHolder holder, int position) {
final FindFriendModel friendModel = findFriendModelList.get(position);
holder.text_view_full_name.setText(friendModel.getFull_name());
StorageReference fileref = FirebaseStorage.getInstance().getReference().child(Constants.IMAGES_FOLDER +"/" + friendModel.getProfileimage());
fileref.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Glide.with(context)
.load(uri)
.placeholder(R.drawable.small_grey_circle)
.error(R.drawable.small_grey_circle)
.into(holder.imageView_profile);
}
});
}
#Override
public int getItemCount() {
return findFriendModelList.size();
}
public class FindFriendsViewHolder extends RecyclerView.ViewHolder{
private CircleImageView imageView_profile;
private TextView text_view_full_name;
private ImageButton button_request, button_cancel_request;
public FindFriendsViewHolder(#NonNull View itemView) {
super(itemView);
imageView_profile = itemView.findViewById(R.id.find_friends_profile_picture);
text_view_full_name = itemView.findViewById(R.id.find_friends_user_full_name);
button_request = itemView.findViewById(R.id.button_send_requests);
button_cancel_request = itemView.findViewById(R.id.button_cancel_requests);
}
}
}
**Model Class**
public class FindFriendModel
{
private String full_name;
private String profileimage;
private String userID;
private boolean requestSent;
public FindFriendModel(String full_name, String profileimage, String userID, boolean requestSent) {
this.full_name= full_name;
this.profileimage = profileimage;
this.userID = userID;
this.requestSent = requestSent;
}
public FindFriendModel() {}
public String getFull_name() {
return full_name;
}
public void setFull_name(String full_name) {
this.full_name = full_name;
}
public String getProfileimage() {
return profileimage;
}
public void setProfileimage(String profileimage) {
this.profileimage = profileimage;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public boolean isRequestSent() {
return requestSent;
}
public void setRequestSent(boolean requestSent) {
this.requestSent = requestSent;
}
}
**Fragment Java Class**
public class FindFriendsFragment extends Fragment {
private RecyclerView recycler_view_find_friends;
private FindFriendsAdapter findFriendsAdapter;
private List<FindFriendModel> findFriendModelList;
private TextView text_view_empty_Friends_List;
private DatabaseReference databaseReference;
private FirebaseUser currentUser;
public FindFriendsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_find_friends, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recycler_view_find_friends = view.findViewById(R.id.recycler_view_find_friends);
text_view_empty_Friends_List = view.findViewById(R.id.text_view_empty_find_friends);
recycler_view_find_friends.setLayoutManager(new LinearLayoutManager(getActivity()));
findFriendModelList = new ArrayList<>();
findFriendsAdapter = new FindFriendsAdapter(getActivity(), findFriendModelList);
recycler_view_find_friends.setAdapter(findFriendsAdapter);
databaseReference = FirebaseDatabase.getInstance().getReference().child("Users");
currentUser = FirebaseAuth.getInstance().getCurrentUser();
text_view_empty_Friends_List.setVisibility(View.VISIBLE);
Query query = databaseReference.orderByChild("full_name");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
findFriendModelList.clear();
for (final DataSnapshot ds : dataSnapshot.getChildren())
{
final String userID = ds.getKey();
if (userID.equals(currentUser.getUid()))
return;
if (ds.child("full_name").getValue()!=null)
{
String fullName = ds.child("full_name").getValue().toString();
String profileImage = ds.child("profileimage").getValue().toString();
findFriendModelList.add(new FindFriendModel(fullName, profileImage, userID, false));
findFriendsAdapter.notifyDataSetChanged();
text_view_empty_Friends_List.setVisibility(View.GONE);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getContext(),"Failed to fetch friends", Toast.LENGTH_SHORT).show();
}
});
}
}
````
ds.child("full_name").getValue()!=null should be replaced by
Objects.equals(ds.child("full_name"), null)
It worked for me when I had the same error, maybe it will help you as well !
Figured out the issue:
The issue was that I was already saving my images images to Firebase Storage, and I was trying to get the download url string again.
I fixed the following part of my adapter:
#Override
public void onBindViewHolder(#NonNull FindFriendsAdapter.FindFriendsViewHolder holder, int position) {
final FindFriendModel friendModel = findFriendModelList.get(position);
holder.text_view_full_name.setText(friendModel.getFull_name());
Glide.with(context)
.load(friendModel.getProfileimage())
.placeholder(R.drawable.small_grey_circle)
.error(R.drawable.small_grey_circle)
.into(holder.imageView_profile);
}
I have recyclerview recieving data from firebase and i want to make last item uploaded to be first item in the list.I'm using GridLayoutManager and want to display a pic with a text, all of this work fine but i want to make them in order like instagram, does any one know something like that ?
Here is my code
public class ItemsUser extends Fragment {
private View mMainView;
private RecyclerView mUsersList;
private String user_id;
private DatabaseReference mUserDatabase;
private FirebaseRecyclerAdapter<ItemRecycleview,UserRecycleView> firebaseRecyclerAdapter;
private DatabaseReference mDatabaseReference;
private FirebaseListAdapter<ItemRecycleview> firebaseListAdapter;
public ItemsUser() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mMainView = inflater.inflate(R.layout.fragment_items_user, container, false);
mUsersList = (RecyclerView) mMainView.findViewById(R.id.recyclerView_profile);
mUsersList.setHasFixedSize(true);
mUsersList.setLayoutManager(new GridLayoutManager(getActivity(),3));
ProfileUser activity = (ProfileUser) getActivity();
user_id = activity.getMyData();
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users_photos").child(user_id);
mUserDatabase.keepSynced(true);
return mMainView;
}
#Override
public void onStart() {
super.onStart();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ItemRecycleview, UserRecycleView>(
ItemRecycleview.class,
R.layout.recycleview_item,
UserRecycleView.class,
mUserDatabase
) {
#Override
protected void populateViewHolder(UserRecycleView viewHolder, ItemRecycleview model, int position) {
viewHolder.setImageName(model.getImageName());
viewHolder.setImageURL(model.getImageURL(),getContext());
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String key = firebaseRecyclerAdapter.getRef(mUsersList.getChildLayoutPosition(v)).getKey();
Intent imageIntent = new Intent(getActivity(), ImageActivity.class);
imageIntent.putExtra("imageKey",key);
imageIntent.putExtra("user_id",user_id);
startActivity(imageIntent);
}
});
}
};
mUsersList.setAdapter(firebaseRecyclerAdapter);
}
public static class UserRecycleView extends RecyclerView.ViewHolder {
View mView;
public UserRecycleView(View itemView) {
super(itemView);
mView = itemView;
}
public void setImageName(String imageName){
TextView userNameView = (TextView) mView.findViewById(R.id.ImageNameTextView);
userNameView.setText(imageName);
}
public void setImageURL(final String imageURL,final Context ctx){
final ImageView userImageView = (ImageView) mView.findViewById(R.id.imageView);
Picasso.with(ctx).load(imageURL).networkPolicy(NetworkPolicy.OFFLINE).into(userImageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(ctx).load(imageURL).into(userImageView);
}
});
}
}
}
and this is ItemRecyclerview:
public class ItemRecycleview {
public String imageName;
public String imageURL;
public ItemRecycleview(){
}
public ItemRecycleview(String imageName, String imageURL) {
this.imageName = imageName;
this.imageURL = imageURL;
}
public String getImageName() {
return imageName;
}
public void setImageName(String imageName) {
this.imageName = imageName;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
}
hey guys i just found the answer :D
all you need to do is to add this method in firebaseRecyclerAdapter
here it's:
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ItemRecycleview, UserRecycleView>(
ItemRecycleview.class,
R.layout.recycleview_item,
UserRecycleView.class,
mUserDatabase
) {
#Override
public ItemRecycleview getItem(int position) {
return super.getItem(getItemCount() - 1 - position);
}
#Override
protected void populateViewHolder(UserRecycleView viewHolder, ItemRecycleview model, int position) {
viewHolder.setImageName(model.getImageName());
viewHolder.setImageURL(model.getImageURL(),getContext());
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String key = firebaseRecyclerAdapter.getRef(mUsersList.getChildLayoutPosition(v)).getKey();
Intent imageIntent = new Intent(getActivity(), ImageActivity.class);
imageIntent.putExtra("imageKey",key);
imageIntent.putExtra("user_id",user_id);
startActivity(imageIntent);
}
});
}
};
and that will make it done
Have you tried using setReverseLayout() method to make first element last in the list
GridLayoutManager mLayoutManager = new GridLayoutManager(getActivity(),3);
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
mUsersList.setLayoutManager(mLayoutManager);
So the problem is following - When mProducts is trying to get the products from the DB in onDataChange() call, then the fragment jumps to onCreateView(), sets the adapter with an empty array and after that performs the database task.
Am I missing something or what am I doing wrong?
Please point out the reason behind this weird behavior.
Thanks.
Fragment class
public class MainViewFragment extends Fragment {
private static final String TAG = "MainViewFragment";
private RecyclerView mView;
private List<Product> mProducts;
private DatabaseReference mRef;
private MainViewAdapter mAdapter;
public MainViewFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_main_view, container, false);
mView = (RecyclerView)v.findViewById(R.id.mainViewRecyclerView);
// mProducts = MockData.getProductData();
mView.setLayoutManager(new LinearLayoutManager(getActivity(),LinearLayoutManager.HORIZONTAL,false));
mAdapter = new MainViewAdapter(mProducts,getActivity());
mView.setAdapter(mAdapter);
return v;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
mRef = FirebaseDatabase.getInstance().getReference().child("products");
mProducts = new ArrayList<>();
new Thread(new Runnable() {
#Override
public void run() {
mRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mProducts = Db.getDatabase(getActivity(),mRef).getProducts();
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
}
}).start();
}
}
Database Class
public class Db {
private DatabaseReference mRef;
private Context ctx;
private static Db sDb;
private List<Product> mProduct;
public static Db getDatabase(Context ctx, DatabaseReference mRef) {
if(sDb == null) {
sDb = new Db(ctx,mRef);
}
return sDb;
}
private Db(Context ctx,DatabaseReference mRef) {
this.ctx = ctx;
this.mRef = mRef;
this.mRef = FirebaseDatabase.getInstance().getReference().child("products");
}
public List<Product> getProducts() {
mProduct = new ArrayList<>();
mRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Iterator<DataSnapshot> dataSnapshotIterator = dataSnapshot.getChildren().iterator();
Product product = null;
while (dataSnapshotIterator.hasNext()) {
DataSnapshot dataSnapshotChild = dataSnapshotIterator.next();
product = dataSnapshotChild.getValue(Product.class);
mProduct.add(product);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
return mProduct;
}
}
In your adapter class, you should have a setter method for your dataset:
public void setData (Dataset dataset) {
mDataset = dataset;
notifyDataSetChanged();
}
In the onAttach:
#Override
public void onAttach(Context context) {
super.onAttach(context);
mRef = FirebaseDatabase.getInstance().getReference().child("products");
mProducts = new ArrayList<>();
new Thread(new Runnable() {
#Override
public void run() {
mRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mProducts = Db.getDatabase(getActivity(),mRef).getProducts();
mAdapter.setData(mProducts)
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
}
}).start();
It could be this line that has the problem
product = dataSnapshotChild.getValue(Product.class);
is not giving the desired result, in which case, I usually desiarialize this way:
Lets say the Product class has two components - name and price which are String and int respectively, I'd have done it this way, if I had a constructor in the Product class with both components as parameters
String name = dataSnapshotChild.child("name").getValue(String.class);
int price= dataSnapshotChild.child("price").getValue(Integer.class);
product = new Product(name, price);
mProduct.add(product);
where "name" and "price" are the node names in your database
// Category Adapter which open the second fragment containing the blank recyclerview(which should ideally contain intial data.)
public class MyCategoryAdapter extends RecyclerView.Adapter<MyCategoryHolder> {
private Context context;
private ArrayList<Categories> categories;
private Context context1;
public MyCategoryAdapter(Context context, ArrayList<Categories> categories) {
this.context = context;
this.categories = categories;
}
#Override
public MyCategoryHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.category_model, parent, false);
context1 = parent.getContext();
return new MyCategoryHolder(v);
}
#Override
public void onBindViewHolder(MyCategoryHolder holder, final int position) {
Categories c = categories.get(position);
holder.categoryText.setText(c.getName());
holder.categoryIdText.setText(c.getId());
//item click
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onItemClick(int pos) {
Toast.makeText(context.getApplicationContext(), Integer.toString(pos), Toast.LENGTH_SHORT).show();
openActivity();
}
});
}
#Override
public int getItemCount() {
return categories.size();
}
private void openActivity()
{
FragmentActivity fragment = ((FragmentActivity)context1);
fragment.getSupportFragmentManager().beginTransaction().addToBackStack(null).replace(R.id.fragment_container, new SubCategoryFragment()).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).commit();
}
}
I have made an android app containing of 2 Recyclerviews. Both have their individual Realm databases. First Recyclerview displays the Categories. When I click on any items, it opens the second Recyclerview for me (containing Subcategories). I am able to load the initial data for the Categories recyclerview but when i click on any items in it, it opens a blank recyclerview (ideally should display the contents from the SubCategories intial data Realm database)
//Realm for SubCategories
public class SubCategories extends RealmObject{
private String name;
private String id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
//Categories intial data
public class CategoriesInitialData implements Realm.Transaction {
#Override
public void execute(Realm realm) {
Categories categories = new Categories();
categories.setName("Animals");
categories.setId("0");
realm.insertOrUpdate(categories);
categories.setName("Birds");
categories.setId("1");
realm.insertOrUpdate(categories);
categories.setName("Mountains");
categories.setId("2");
realm.insertOrUpdate(categories);
categories.setName("Instagram");
categories.setId("3");
realm.insertOrUpdate(categories);
categories.setName("Facebook");
categories.setId("4");
realm.insertOrUpdate(categories);
categories.setName("Twitter");
categories.setId("5");
realm.insertOrUpdate(categories);
categories.setName("OnePlus");
categories.setId("6");
realm.insertOrUpdate(categories);
categories.setName("Apple");
categories.setId("7");
realm.insertOrUpdate(categories);
categories.setName("Samsung");
categories.setId("8");
realm.insertOrUpdate(categories);
categories.setName("Laptops");
categories.setId("9");
realm.insertOrUpdate(categories);
categories.setName("Food");
categories.setId("10");
realm.insertOrUpdate(categories);
categories.setName("Lifestyle");
categories.setId("11");
realm.insertOrUpdate(categories);
}
#Override
public int hashCode() {
return CategoriesInitialData.class.hashCode();
}
#Override
public boolean equals(Object obj) {
return obj != null && obj instanceof CategoriesInitialData;
}
}
// SubCategories Initial Data
public class SubCategoriesInitialData implements Realm.Transaction {
#Override
public void execute(Realm realm) {
SubCategories subCategories = new SubCategories();
subCategories.setName("Animals1");
subCategories.setId("0");
realm.insertOrUpdate(subCategories);
subCategories.setName("Animals2");
subCategories.setId("0");
realm.insertOrUpdate(subCategories);
subCategories.setName("Animals3");
subCategories.setId("0");
realm.insertOrUpdate(subCategories);
subCategories.setName("Birds1");
subCategories.setId("1");
realm.insertOrUpdate(subCategories);
subCategories.setName("Birds2");
subCategories.setId("1");
realm.insertOrUpdate(subCategories);
subCategories.setName("Birds3");
subCategories.setId("1");
realm.insertOrUpdate(subCategories);
}
#Override
public int hashCode() {
return SubCategoriesInitialData.class.hashCode();
}
#Override
public boolean equals(Object obj) {
return obj != null && obj instanceof SubCategoriesInitialData;
}
}
// Category Fragment
public class CategoryFragment extends Fragment {
Realm realm;
MyCategoryAdapter myCategoryAdapter;
RealmChangeListener realmChangeListener;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.fragment_categories,container,false);
final RecyclerView rv = (RecyclerView) myView.findViewById(R.id.categoryRV);
rv.setLayoutManager(new LinearLayoutManager(this.getActivity()));
//Realm configuration
Realm.init(getContext());
RealmConfiguration configuration = new RealmConfiguration.Builder().initialData(new CategoriesInitialData()).deleteRealmIfMigrationNeeded().build();
realm = Realm.getInstance(configuration);
//Save
final CategoriesRealmHelper helper = new CategoriesRealmHelper(realm);
//Categories categories = new Categories();
//categories.setName("Last Category");
//helper.save(categories);
//retrieve
helper.retrieveCategories();
//setup adapter
myCategoryAdapter = new MyCategoryAdapter(getContext(), helper.refreshCategories());
rv.setAdapter(myCategoryAdapter);
//data change
realmChangeListener = new RealmChangeListener() {
#Override
public void onChange(Object element) {
//refresh
myCategoryAdapter = new MyCategoryAdapter(getContext(), helper.refreshCategories());
rv.setAdapter(myCategoryAdapter);
}
};
//add changes to realm
realm.addChangeListener(realmChangeListener);
return myView;
}
#Override
public void onDestroyView() {
super.onDestroyView();
realm.removeChangeListener(realmChangeListener);
realm.close();
}
#Override
public void onStop() {
super.onStop();
}
}
// SubCategories Fragment
public class SubCategoryFragment extends Fragment {
Realm realm;
MySubCategoryAdapter mySubCategoryAdapter;
RealmChangeListener realmChangeListener;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.fragment_subcategories, container, false);
final RecyclerView rv = (RecyclerView) myView.findViewById(R.id.subcategoryRV);
rv.setLayoutManager(new LinearLayoutManager(this.getActivity()));
//Realm configuration
Realm.init(getContext());
RealmConfiguration configuration = new RealmConfiguration.Builder().initialData(new SubCategoriesInitialData()).deleteRealmIfMigrationNeeded().build();
realm = Realm.getInstance(configuration);
//Save
final SubCategoriesRealmHelper helper = new SubCategoriesRealmHelper(realm);
//SubCategories subCategories = new SubCategories();
//subCategories.setName("Hello");
//helper.save(subCategories);
//retrieve
helper.retrieveSubCategories();
//setting up adapter
mySubCategoryAdapter = new MySubCategoryAdapter(getContext(), helper.refreshSubCategories());
rv.setAdapter(mySubCategoryAdapter);
//data change
realmChangeListener = new RealmChangeListener() {
#Override
public void onChange(Object element) {
//refresh
mySubCategoryAdapter = new MySubCategoryAdapter(getContext(), helper.refreshSubCategories());
rv.setAdapter(mySubCategoryAdapter);
}
};
//add changes to realm
realm.addChangeListener(realmChangeListener);
return myView;
}
#Override
public void onDestroyView() {
super.onDestroyView();
realm.removeChangeListener(realmChangeListener);
realm.close();
}
#Override
public void onStop() {
super.onStop();
}
}
// Realm Helper class. I also have a CategoriesRealmHelper class having similar methods
public class SubCategoriesRealmHelper {
Realm realm;
boolean saved;
RealmResults<SubCategories> subCategories;
public SubCategoriesRealmHelper(Realm realm) {
this.realm = realm;
}
//Writing data to subcategories database
public boolean save(final SubCategories subCategories)
{
if(subCategories == null)
{
saved = false;
}
else
{
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
try{
realm.copyToRealm(subCategories);
saved = true;
}catch (RealmException e)
{
e.printStackTrace();
saved = false;
}
}
});
}
return saved;
}
//reading data from subcategories database
public void retrieveSubCategories()
{
subCategories = realm.where(SubCategories.class).findAll();
}
//refreshing subcategories data
public ArrayList<SubCategories> refreshSubCategories()
{
ArrayList<SubCategories> latest = new ArrayList<>();
for (SubCategories s : subCategories) {
latest.add(s);
}
return latest;
}
}
//Main Acitivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
openFragment();
}
void openFragment(){
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new CategoryFragment()).commit();
}
}
//Realm for Categories
public class Categories extends RealmObject {
private String name;
private String id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
what can be the reason that firebase gives databaseException error? I am new to android firebase adapter and I am facing an issue of databaseException. I was trying to get adapter in MainCommentFragment so I can use viewPager and recyclerview. But it seems like there is an error when I call mRecyclerView.setAdapter(mCommentAdapter); in MainCommentFragment.java. Can anyone help me with this?
Comment.java
public class Comment
{
public String uid;
public String username;
public String body;
public String time;
public String choice;
public int likeCount;
public int dislikeCount;
public Map<String, Boolean> likes = new HashMap<>();
public Map<String, Boolean> dislikes = new HashMap<>();
public Comment()
{
}
public Comment(String uid, String username, String body, String time, String choice)
{
this.uid = uid;
this.username = username;
this.body = body;
this.time = time;
this.choice = choice;
}
public Map<String, Object> toMap()
{
HashMap<String, Object> result = new HashMap<>();
result.put("uid", uid);
result.put("username", username);
result.put("time", time);
result.put("body", body);
result.put("likeCount", likeCount);
result.put("dislikeCount", dislikeCount);
result.put("likes", likes);
result.put("dislikes", dislikes);
result.put("choice", choice);
return result;
}
}
MainCommentFragment.java
public abstract class MainCommentFragment extends Fragment
{
/*UI*/
private RecyclerView mRecyclerView; //declaring recycler view
/*Firebase*/
private DatabaseReference mDatabase; //declaring database
/*Other*/
private FirebaseRecyclerAdapter<Comment, CommentViewHolder> mCommentAdapter; //declaring adapter for post
private LinearLayoutManager mLinearLayoutManager; //declaring linear layout manager
private String postKey;
/*Function*/
public MainCommentFragment() //creating a constructor for MainFragment
{
}
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) //when view is created
{
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.fragment_comment, container, false); //fragment_all_posts will invoked
mDatabase = FirebaseDatabase.getInstance().getReference(); //initializing database
mRecyclerView = (RecyclerView)rootView.findViewById(R.id.fragment_comment_recycler_view); //initializing recycler view
mRecyclerView.setHasFixedSize(true); //giving fixed size property to recycler view
RoomActivity roomActivity = (RoomActivity)getActivity();
postKey = roomActivity.getPostKey();
System.out.println("postKey=============================" + postKey);
return rootView; //returning view
}
#Override
public void onActivityCreated(Bundle savedInstanceState) //when activity is created
{
super.onActivityCreated(savedInstanceState);
mLinearLayoutManager = new LinearLayoutManager(getActivity()); //initializing linear layout manager
mLinearLayoutManager.setReverseLayout(true); //make the layout reverse
mLinearLayoutManager.setStackFromEnd(true); //make the layout stack from end
mRecyclerView.setLayoutManager(mLinearLayoutManager); //initialize recycler view
Query commentQuery = getQuery(mDatabase, postKey); //get query for database
mCommentAdapter = new FirebaseRecyclerAdapter<Comment, CommentViewHolder>(Comment.class, R.layout.comment_item, CommentViewHolder.class, commentQuery) //initializing post adapter
{
#Override
protected void populateViewHolder(CommentViewHolder viewHolder, Comment model, int position)
{
viewHolder.bindToComment(model, new View.OnClickListener()
{
#Override
public void onClick(View v)
{
DatabaseReference globalCommentRef = mDatabase.child("Comment").child(postKey);
onLikeClicked(globalCommentRef);
switch(v.getId())
{
case R.id.comment_item_like_btn:
onLikeClicked(globalCommentRef);
break;
case R.id.comment_item_dislike_btn:
onDislikeClicked(globalCommentRef);
break;
}
}
});
}
};
mRecyclerView.setAdapter(mCommentAdapter); //recycler view will not display post adapter
}
private void onLikeClicked(DatabaseReference commentRef)
{
commentRef.runTransaction(new Transaction.Handler()
{
#Override
public Transaction.Result doTransaction(MutableData mutableData)
{
Comment c = mutableData.getValue(Comment.class);
if(c == null)
{
return Transaction.success(mutableData);
}
if(c.likes.containsKey(FirebaseAuth.getInstance().getCurrentUser().getUid()))
{
} else
{
c.likeCount = c.likeCount + 1;
c.likes.put(FirebaseAuth.getInstance().getCurrentUser().getUid(), true);
if(c.dislikeCount != 0)
{
c.dislikeCount = c.dislikeCount - 1;
c.dislikes.remove(FirebaseAuth.getInstance().getCurrentUser().getUid());
}
}
mutableData.setValue(c);
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot)
{
}
});
}
private void onDislikeClicked(DatabaseReference commentRef)
{
commentRef.runTransaction(new Transaction.Handler()
{
#Override
public Transaction.Result doTransaction(MutableData mutableData)
{
Comment c = mutableData.getValue(Comment.class);
if(c == null)
{
return Transaction.success(mutableData);
}
if(c.dislikes.containsKey(FirebaseAuth.getInstance().getCurrentUser().getUid()))
{
} else
{
c.dislikeCount = c.dislikeCount + 1;
c.dislikes.put(FirebaseAuth.getInstance().getCurrentUser().getUid(), true);
if(c.likeCount != 0)
{
c.likeCount = c.likeCount - 1;
c.likes.remove(FirebaseAuth.getInstance().getCurrentUser().getUid());
}
}
mutableData.setValue(c);
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot)
{
}
});
}
public abstract Query getQuery(DatabaseReference databaseReference, String postKey); //declaring query
}
This is the error message.
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Long to type packagename.Comment