I am very new to android and developing an app which will fetch some data from Firebase realtime database and show data on UI. but whenever app is loaded just nothing happened. In the Logcat window it is continuously
showing:
D/KeyguardUpdateMonitor: received broadcast
android.intent.action.BATTERY_CHANGED
D/KeyguardUpdateMonitor: handleBatteryUpdate
I/BatteryInfoReceiver: ACTION_BATTERY_CHANGED
W/QCNEJ: |CORE| CNE received unexpected action:
android.intent.action.BATTERY_CHANGED
i have also tried to search it out but can't understand..
just want to know
what is the mean of this
"android.intent.action.BATTERY_CHANGED"
and why its not showing any data on UI.
my firebase realtime database rules (read/write) are set to true. because i am just trying something..
is there any problem with permissions or manifest file? because i
don't have included any of the permissions in app..
i am using my redmi note 4 for testing app.
code for the app is here..
Model class.
public class ad {
private String adImage, SellerID, price, location, adTitle, adDescription;
public ad(){
}
public ad(String adImage, String seller, String price, String location, String adTitle, String description) {
this.adImage = adImage;
this.SellerID = seller;
this.price = price;
this.location = location;
this.adTitle = adTitle;
this.adDescription = description;
}
public String getAdImage() {
return adImage;
}
public void setAdImage(String adImage) {
this.adImage = adImage;
}
public String getSellerID() {
return SellerID;
}
public void setSellerID(String seller) {
this.SellerID = seller;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getAdTitle() {
return adTitle;
}
public void setAdTitle(String adTitle) {
this.adTitle = adTitle;
}
public String getAdDescription() {
return adDescription;
}
public void setAdDescription(String adDescription) {
this.adDescription = adDescription;
}
}
my adsViewHolder class
public class adsViewHolder extends RecyclerView.ViewHolder {
public ImageView ad_image ;
public TextView ad_title ;
public TextView ad_price ;
public TextView ad_location;
public adsViewHolder(#NonNull View itemView) {
super(itemView);
ad_image = (ImageView)itemView.findViewById(R.id.defPic);
ad_title = (TextView)itemView.findViewById(R.id.adTitle);
ad_price = (TextView)itemView.findViewById(R.id.adPrice);
ad_location = (TextView)itemView.findViewById(R.id.AdCityName);
}
}
my AdsProfile Activity code for fetching and shwoing data on ui.
public class AdsProfile extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private RecyclerView AdsListRecyclerView;
private DatabaseReference mRef;
FirebaseRecyclerOptions<ad> options;
FirebaseRecyclerAdapter<ad, adsViewHolder> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ads_profile);
AdsListRecyclerView = (RecyclerView)findViewById(R.id.Ads_Display_Recycler_View);
AdsListRecyclerView.setHasFixedSize(true);
mRef = FirebaseDatabase.getInstance().getReference("ads");
options = new FirebaseRecyclerOptions.Builder<ad>()
.setQuery(mRef, ad.class).build();
adapter = new FirebaseRecyclerAdapter<ad, adsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull adsViewHolder holder, int position, #NonNull ad model) {
holder.ad_title.setText(model.getAdTitle());
holder.ad_price.setText(model.getPrice());
holder.ad_location.setText(model.getLocation());
}
#NonNull
#Override
public adsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.ad_layout,viewGroup,false);
return new adsViewHolder(view);
}
};
AdsListRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
adapter.startListening();
AdsListRecyclerView.setAdapter(adapter);
}
}
Related
I tried to make a covid-19 tracking app by watching Youtube tutorials.
My app shows the country list with flags and when you click on any country it opens an activity and shows the details of that country i.e total cases, deaths, recovered, etc. The video on Youtube uses ListView and I am using recyclerView
I fetched the country list successfully and set onClickListener on the view and it opens second activity which shows the case in detail. But I don't know how to show the data.
my adapter class:
class Countries_adapter extends RecyclerView.Adapter<Countries_adapter.MyViewHolder> {
Context ct;
List<Countries_data> list;
public Countries_adapter(Context context,List<Countries_data> country)
{
ct=context;
list=country;
}
#Override
public MyViewHolder onCreateViewHolder( ViewGroup parent, int viewType) {
View v = LayoutInflater.from(ct).inflate(R.layout.countries_row,parent,false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.tvCountryName.setText(list.get(position).getCountry());
holder.tvtotal.setText(list.get(position).getActive());
Glide.with(ct).load(list.get(position).getFlag()).into(holder.imageView);
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(ct,CountriesDetails.class);
i.putExtra("Country",list.get(position).getCountry());
ct.startActivity(i);
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvCountryName,tvtotal;
ImageView imageView;
LinearLayout linearLayout;
public MyViewHolder( View itemView) {
super(itemView);
tvCountryName = itemView.findViewById(R.id.tvCountryName);
tvtotal=itemView.findViewById(R.id.tvCountrytotalcaese);
imageView = itemView.findViewById(R.id.imageFlag);
linearLayout=itemView.findViewById(R.id.linear_layout);
}
}
my AffectedCoutries class activity is as follows:
public class AffectedCountries extends AppCompatActivity {
EditText edtSearch;
RecyclerView recyclerView;
SimpleArcLoader simpleArcLoader;
public static ArrayList countryList = new ArrayList<>();
Countries_data countryData;
Countries_adapter CountriesAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_affected_countries);
edtSearch = findViewById(R.id.edtSearch);
recyclerView=findViewById(R.id.recyclerAffectedCountries);
simpleArcLoader = findViewById(R.id.loader);
fetchData();
}
private void fetchData() {
String url = "https://corona.lmao.ninja/v2/countries/";
simpleArcLoader.start();
StringRequest request = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for(int i=0;i<jsonArray.length();i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String countryName = jsonObject.getString("country");
String cases = jsonObject.getString("cases");
String todayCases = jsonObject.getString("todayCases");
String deaths = jsonObject.getString("deaths");
String todayDeaths = jsonObject.getString("todayDeaths");
String recovered = jsonObject.getString("recovered");
String active = jsonObject.getString("active");
String critical = jsonObject.getString("critical");
JSONObject object = jsonObject.getJSONObject("countryInfo");
String flagUrl = object.getString("flag");
countryData = new Countries_data(flagUrl,countryName,cases,todayCases,deaths,todayDeaths,recovered,active,critical);
countryList.add(countryData);
}
CountriesAdapter = new Countries_adapter(AffectedCountries.this,countryList);
recyclerView.setLayoutManager(new LinearLayoutManager(AffectedCountries.this));
recyclerView.setAdapter(CountriesAdapter);
simpleArcLoader.stop();
simpleArcLoader.setVisibility(View.GONE);
} catch (JSONException e) {
e.printStackTrace();
simpleArcLoader.start();
simpleArcLoader.setVisibility(View.GONE);
Toast.makeText(AffectedCountries.this,"catch response", Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
simpleArcLoader.stop();
simpleArcLoader.setVisibility(View.GONE);
Toast.makeText(AffectedCountries.this,"error response", Toast.LENGTH_SHORT).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(request);
}
}
my Countries_data class(model class)
public class Countries_data {
public String country;
public String cases;
public String todayCases;
public String deaths;
public String todayDeaths;
public String recovered;
public String active;
public String critical;
public String flag;
public Countries_data(String flag, String country, String cases, String
todayCases, String deaths, String todayDeaths, String recovered,
String active, String critical) {
this.country = country;
this.cases = cases;
this.todayCases = todayCases;
this.deaths = deaths;
this.todayDeaths = todayDeaths;
this.recovered = recovered;
this.active = active;
this.critical = critical;
this.flag = flag;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCases() {
return cases;
}
public void setCases(String cases) {
this.cases = cases;
}
public String getTodayCases() {
return todayCases;
}
public void setTodayCases(String todayCases) {
this.todayCases = todayCases;
}
public String getDeaths() {
return deaths;
}
public void setDeaths(String deaths) {
this.deaths = deaths;
}
public String getTodayDeaths() {
return todayDeaths;
}
public void setTodayDeaths(String todayDeaths) {
this.todayDeaths = todayDeaths;
}
public String getRecovered() {
return recovered;
}
public void setRecovered(String recovered) {
this.recovered = recovered;
}
public String getActive() {
return active;
}
public void setActive(String active) {
this.active = active;
}
public String getCritical() {
return critical;
}
public void setCritical(String critical) {
this.critical = critical;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
}
my Country_details class
public class CountriesDetails extends AppCompatActivity {
TextView tvCountry, tvCases, tvRecovered,tvdeaths;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_countries_details2);
tvCountry = findViewById(R.id.tvCountry);
tvCases = findViewById(R.id.tvCases);
tvRecovered = findViewById(R.id.tvRecovered);
tvdeaths=findViewById(R.id.tvTotalDeaths);
String positionCountry = getIntent().getStringExtra("Country");
Log.i("country name", positionCountry);
}
}
How to set the data in tvcases?
How can I show the data? Do I have to create a separate recycler view and then fetch the data from the API or can I use my main activity to show the data?
I have some sad information for you: Google Play policy restricts such apps from being published in store... especially when you are showing deaths count. Been there, done that, my app was blocked...
besides above:
you are passing country name in intent:
i.putExtra("Country",list.get(position).getCountry());
but trying to read "position" in details Activity - it will be always 0 (default)
edit due to comments:
pass position of clicked View
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(ct,CountriesDetails.class);
i.putExtra("position", position);
ct.startActivity(i);
}
});
in CountriesDetailss onCreate method receive this position and restore proper Countries_data object from your static countryList array in AffectedCountries
int position = getIntent().getIntExtra("position", 0);
Countries_data country = AffectedCountries.countryList.get(position);
tvCountry.setText(country.getCountry());
that should work, but this isn't best way to store data, in fact its very weak... after downloading data (list of countries) you should store it somehow, e.g. SQLite/Room lib or at least SharedPreferences... then in details activity you should restore int position and using it take proper object from database or preferences, instead of stright from static array
it may be also useful to implement Parcelable inteface to your Countries_data - this will allow to put whole Countries_data object into Intents extras, not only primitive int with position in array. in this case details activity won't even need access to whole array or sql database/preferences, it will get whole object straight from Intents extras
I am trying to retrieve data (a product image and the price for it) from Firebase Realtime Database and put it in a recyclerView, but I have some difficulties. In my database I stored the image url for one product and I want to show that image in an ImageView component placed in the cardView. I also managed to retrieve the url and price correctly, but my recyclerView doesn't show them.
This is my product class:
public class CustomizeProduct {
private String productImage;
private String productName;
private String productPrice;
public CustomizeProduct(String image, String name, String price){
this.productImage = image;
this.productName = name;
this.productPrice = price;
}
public String getProductImage() {
return productImage;
}
public void setProductImage(String productImage){
this.productImage = productImage;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName){
this.productName = productName;
}
public String getProductPrice() { return productPrice; }
public void setProductPrice(String productPrice) {
this.productPrice = productPrice;
}
}
My Adapter as following:
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder> {
private ArrayList<CustomizeProduct> customized;
private Context myContext;
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView thisProductImage;
public TextView thisProductName;
public TextView thisProductPrice;
public ViewHolder(View itemView) {
super(itemView);
thisProductImage = itemView.findViewById(R.id.customProductImage);
thisProductName = itemView.findViewById(R.id.customProductName);
thisProductPrice = itemView.findViewById(R.id.customProductPrice);
}
}
public ProductAdapter(Context context, ArrayList<CustomizeProduct> thisCustom) {
myContext = context;
customized = thisCustom;
}
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.ingredients, parent, false);
ViewHolder mv = new ViewHolder(v);
return mv;
}
public void onBindViewHolder(ViewHolder holder, int position) {
CustomizeProduct currentCustom = customized.get(position);
Picasso.get().load(currentCustom.getProductImage()).placeholder(R.drawable.shrimp_ditali).into(holder.thisProductImage);
holder.thisProductName.setText(currentCustom.getProductName());
holder.thisProductPrice.setText(currentCustom.getProductPrice());
}
public int getItemCount() {
return customized.size();
}
}
And the activity I have placed my recyclerView:
public class BuildProduct extends AppCompatActivity {
public final static ArrayList<CustomizeProduct> customized = new ArrayList<>();
private RecyclerView recyclerView;
private ProductAdapter myAdapter;
private RecyclerView.LayoutManager layoutManager;
private static String productImage, productPrice;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_build_product);
buildCustom();
}
public void buildCustom(){
recyclerView = findViewById(R.id.customList);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("MENIU");
ref.addListenerForSingleValueEvent(new ValueEventListener(){
public void onDataChange(DataSnapshot ds) {
for (DataSnapshot menu : ds.getChildren()) {
String keys = menu.getKey();
String productName = (String) ds.child(keys).child("NUME_PRODUS").getValue();
if(productName.equals(checkout.thisProductName)){
productImage = ds.child(keys).child("IMAGINE").getValue(String.class);
Long price = (Long) ds.child(keys).child("PRET_PRODUS").getValue();
productPrice = String.valueOf(price);
Toast.makeText(getApplicationContext(), productImage + " " + productPrice, Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
for(int i = 0; i < checkout.thisProductQty; i++) {
customized.add(new CustomizeProduct(productImage,checkout.thisProductName, productPrice));
myAdapter = new ProductAdapter(getApplicationContext(), customized);
}
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(myAdapter);
}
}
The product name is correctly because is a variable, but the image and price don't change at all. The "for" loop serves in creating as much cardViews as my products of that type are in checkout.
How can I make it show image and price from database?
This is my Firebase child structure:
EDIT
Updated code:
public class CustomizeProduct {
private String imagine;
private String nume_produs;
private String pret_produs;
public CustomizeProduct(){}
public CustomizeProduct(String imagine, String nume_produs, String pret_produs){
this.imagine = imagine;
this.nume_produs = nume_produs;
this.pret_produs = pret_produs;
}
#PropertyName("IMAGINE")
public String getIMAGINE() {
return imagine;
}
#PropertyName("NUME_PRODUS")
public String getNUME_PRODUS() {
return nume_produs;
}
#PropertyName("PRET_PRODUS")
public String getPRET_PRODUS() { return pret_produs; }
}
And in onBindViewHolder:
public void onBindViewHolder(ViewHolder holder, int position) {
CustomizeProduct currentCustom = customized.get(position);
Picasso.get().load(currentCustom.getIMAGINE()).placeholder(R.drawable.shrimp_ditali).into(holder.thisProductImage);
holder.thisProductName.setText(currentCustom.getNUME_PRODUS());
holder.thisProductPrice.setText(currentCustom.getPRET_PRODUS());
}
customized.add(new CustomizeProduct(productImage,checkout.thisProductName, productPrice));
You can see only product name (checkout.thisProductName), but not product image & price because you populate your adapter with product names that is not returned by Firebase in your onDataChange(DataSnapshot ds) callback; there is no clue in your code how do you build product names (checkout.thisProductName) value.
Now product images & prices not shown as you build the adapter in the main thread, while firebase works implicitly in background thread; so you need to sync your adapter to that background thread by transferring the part of code that builds your recyclerView adapter into the firebase callback as follow:
public void buildCustom(){
recyclerView = findViewById(R.id.customList);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("MENIU");
ref.addListenerForSingleValueEvent(new ValueEventListener(){
public void onDataChange(DataSnapshot ds) {
for (DataSnapshot menu : ds.getChildren()) {
String keys = menu.getKey();
String productName = (String) ds.child(keys).child("NUME_PRODUS").getValue();
if(productName.equals(checkout.thisProductName)){
productImage = ds.child(keys).child("IMAGINE").getValue(String.class);
Long price = (Long) ds.child(keys).child("PRET_PRODUS").getValue();
productPrice = String.valueOf(price);
Toast.makeText(getApplicationContext(), productImage + " " + productPrice, Toast.LENGTH_LONG).show();
}
}
// here you've received all Firebase data and can now build the recyclerView
for(int i = 0; i < checkout.thisProductQty; i++) {
customized.add(new CustomizeProduct(productImage,checkout.thisProductName, productPrice));
myAdapter = new ProductAdapter(getApplicationContext(), customized);
}
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(myAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
I think you may also have to annotate the private fields, since the SDK uses those to set the values from the database:
public class CustomizeProduct {
#PropertyName("IMAGINE")
private String imagine;
#PropertyName("NUME_PRODUS")
private String nume_produs;
#PropertyName("PRET_PRODUS")
private String pret_produs;
public CustomizeProduct(){}
public CustomizeProduct(String imagine, String nume_produs, String pret_produs){
this.imagine = imagine;
this.nume_produs = nume_produs;
this.pret_produs = pret_produs;
}
#PropertyName("IMAGINE")
public String getIMAGINE() {
return imagine;
}
#PropertyName("NUME_PRODUS")
public String getNUME_PRODUS() {
return nume_produs;
}
#PropertyName("PRET_PRODUS")
public String getPRET_PRODUS() { return pret_produs; }
}
Note that using getters and setters is completely optional, and you also use this (much shorter) class to bind to the same JSON structure:
public class CustomizeProduct {
#PropertyName("IMAGINE")
public String imagine;
#PropertyName("NUME_PRODUS")
public String nume_produs;
#PropertyName("PRET_PRODUS")
public String pret_produs;
}
I created an app and I store some data in a Firebase Firestore, everytime I want to fetch the data and display them in a RecyclerView I get this
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.****, PID: 9052
java.lang.ClassCastException: java.util.HashMap cannot be cast to com.example.****.Models.Comments
at com.example.****.Utils.CommentsAdapter.onBindViewHolder(CommentsAdapter.java:43)
at com.example.****.Utils.CommentsAdapter.onBindViewHolder(CommentsAdapter.java:19)
....
I really don't know what I did wrong, can you please look over my code and tell me where I'm wrong?
Here's the Adapter:
public class CommentsAdapter extends RecyclerView.Adapter<CommentsAdapter.CommentsViewHolder> {
Context mContext;
List<Comments> mData;
public CommentsAdapter(Context mContext, List<Comments> mData) {
this.mContext = mContext;
this.mData = mData;
}
#NonNull
#Override
public CommentsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View layout;
layout = LayoutInflater.from(mContext).inflate(R.layout.item_comments, parent, false);
return new CommentsViewHolder(layout);
}
#Override
public void onBindViewHolder(#NonNull CommentsViewHolder holder, int i) {
//bind data
holder.title.setText(mData.get(i).getTitle());
holder.content.setText(mData.get(i).getContent());
Glide.with(mContext).load(mData.get(i).getPicUploadedBy()).into(holder.pictureProfile);
}
#Override
public int getItemCount() {
return mData.size();
}
public class CommentsViewHolder extends RecyclerView.ViewHolder {
TextView content, title;
ImageView pictureProfile;
public CommentsViewHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.textTitle);
content = itemView.findViewById(R.id.textContent);
pictureProfile = itemView.findViewById(R.id.profileUser);
}
}
}
Here's the activity where I use this:
public class ProfileActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
mAuth = FirebaseAuth.getInstance();
db = FirebaseFirestore.getInstance();
mStorageRef = FirebaseStorage.getInstance().getReference("users-images");
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if(user != null)
{
db.collection("Users").whereEqualTo("email", user.getEmail())
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful())
{
for(QueryDocumentSnapshot documentSnapshot: task.getResult()) {
String fullname = documentSnapshot.get("fullname").toString();
String address = documentSnapshot.get("address").toString();
String city = documentSnapshot.get("city").toString();
String state = documentSnapshot.get("state").toString();
String country = documentSnapshot.get("country").toString();
String phone = documentSnapshot.get("phone").toString();
String zipcode = documentSnapshot.get("zipcode").toString();
String type = documentSnapshot.get("type").toString();
String rate = documentSnapshot.get("rate").toString();
Boolean isActivated = documentSnapshot.getBoolean("isActivated");
List<Card> cards= (List<Card>) documentSnapshot.get("cards");
List<Comments> comments = (List<Comments>) documentSnapshot.get("comments");
List<Documents> documents = (List<Documents>) documentSnapshot.get("documents");
String profilePic = documentSnapshot.get("profilePic").toString();
String email = documentSnapshot.get("email").toString();
String password = documentSnapshot.get("password").toString();
mUser = new User(
fullname,
address,
city,
state,
country,
phone,
zipcode,
type,
rate,
isActivated,
cards,
comments,
documents,
profilePic,
email,
password
);
myProfileDo(mUser);
}
}
}
});
private void myProfileDo(User mUser) {
List<Comments> commentsList = new ArrayList<>();
fullnameView.setText(mUser.getFullname());
addressView.setText(mUser.getAddress());
rateView.setText(mUser.getRate());
Glide.with(this).load(mUser.getProfilePic()).into(profilePic);
for(int i = 0 ;i < mUser.getComments().size();i++) {
commentsList.add(mUser.getComments().get(i));
}
commentsAdapter = new CommentsAdapter(this,commentsList);
rvComments.setAdapter(commentsAdapter);
rvComments.setLayoutManager(new LinearLayoutManager(this));
}
}
And The Model "Comments" :
public class Comments {
public String uploadedBy;
public String picUploadedBy;
public String title;
public String content;
public Comments(String uploadedBy, String picUploadedBy, String title, String content) {
this.uploadedBy = uploadedBy;
this.picUploadedBy = picUploadedBy;
this.title = title;
this.content = content;
}
public String getUploadedBy() {
return uploadedBy;
}
public void setUploadedBy(String uploadedBy) {
this.uploadedBy = uploadedBy;
}
public String getPicUploadedBy() {
return picUploadedBy;
}
public void setPicUploadedBy(String picUploadedBy) {
this.picUploadedBy = picUploadedBy;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
The data is fetched well, if I println the "commentsList" it's not null, must be something on the adapter or the way I implement the adapter.
Thank you in advance!
I'm having a problem retrieving the payments data. It always says I can't convert object type to:
com.google.firebase.database.DatabaseException: Can't convert object
of type java.lang.String to type
com.pasarkaget.fajar.pasarkaget.Model.Payments
I'm think this error from my model payments but I don't know my mistake. Anyone can help me?
This My AdminUserPaymentsActivity where I must display the payments data certain user.
public class AdminUserPaymentActivity extends AppCompatActivity
{
private RecyclerView paymentsList;
RecyclerView.LayoutManager layoutManager;
private DatabaseReference paymentsRef;
private String userID = "";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_user_payments);
userID = getIntent().getStringExtra("uid");
paymentsList = findViewById(R.id.payments_list);
paymentsList.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
paymentsList.setLayoutManager(layoutManager);
paymentsRef = FirebaseDatabase.getInstance().getReference()
.child("Cart List").child("Admin View").child(userID).child("Payments");
}
#Override
protected void onStart()
{
super.onStart();
FirebaseRecyclerOptions<Payments> options =
new FirebaseRecyclerOptions.Builder<Payments>()
.setQuery(paymentsRef, Payments.class)
.build();
FirebaseRecyclerAdapter<Payments, PaymentsViewHolder> adapter = new FirebaseRecyclerAdapter<Payments, PaymentsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull PaymentsViewHolder holder, int position, #NonNull Payments model)
{
holder.txtMyBankName.setText(model.getBuyerBank());
holder.txtBankAccountName.setText(model.getBuyerAccount());
holder.txtBankName.setText(model.getBank());
holder.txtMetods.setText(model.getMetods());
holder.txtTotalTransfer.setText("Rp " + model.getNominal());
holder.txtState.setText(model.getState());
holder.txtDate.setText("Pada Tanggal : " + model.getDate());
}
#NonNull
#Override
public PaymentsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.payments_items_layout, parent, false);
PaymentsViewHolder holder = new PaymentsViewHolder(view);
return holder;
}
};
paymentsList.setAdapter(adapter);
adapter.startListening();
}
}
My Viewholder Class
public class PaymentsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
public TextView txtBankName, txtMyBankName, txtBankAccountName, txtTotalTransfer, txtMetods, txtState, txtDate;
private ItemClickListener itemClickListener;
public PaymentsViewHolder(View itemView)
{
super(itemView);
txtBankName = itemView.findViewById(R.id.payments_bank_destination);
txtMyBankName = itemView.findViewById(R.id.payments_bank_name);
txtBankAccountName = itemView.findViewById(R.id.payments_bank_account);
txtTotalTransfer = itemView.findViewById(R.id.payments_total_transfer);
txtMetods = itemView.findViewById(R.id.payments_bank_metods);
txtState = itemView.findViewById(R.id.payments_state);
txtDate = itemView.findViewById(R.id.payments_date);
}
#Override
public void onClick(View view)
{
itemClickListener.onClick(view, getAdapterPosition(), false);
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
}
And Lastly, My Model Payments class
public class Payments
{
private String bank, buyerBank, buyerAccount, nominal, metods, state, date, time;
public Payments()
{
}
public Payments(String bank, String buyerBank, String buyerAccount, String nominal, String metods, String state, String date, String time)
{
this.bank = bank;
this.buyerBank = buyerBank;
this.buyerAccount = buyerAccount;
this.nominal = nominal;
this.metods = metods;
this.state= state;
this.date = date;
this.time = time;
}
public String getBank() {
return bank;
}
public void setBank(String bank) {
this.bank = bank;
}
public String getBuyerBank() {
return buyerBank;
}
public void setBuyerBank(String buyerBank) {
this.buyerBank = buyerBank;
}
public String getBuyerAccount() {
return buyerAccount;
}
public void setBuyerAccount(String buyerAccount) {
this.buyerAccount = buyerAccount;
}
public String getNominal() {
return nominal;
}
public void setNominal(String nominal) {
this.nominal = nominal;
}
public String getMetods() {
return metods;
}
public void setMetods(String metods) {
this.metods = metods;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
My Firebase database structured:
my structured firebase
When you are passing your paymentsRef to the FirebaseRecyclerOptions<Payments> object it means that you are looking for Payments objects but within your reference, there are only objects of type String and not Payments, and that's why you get that error. To solve this, simply remove the call to .child("Payments"):
paymentsRef = FirebaseDatabase.getInstance().getReference()
.child("Cart List").child("Admin View").child(userID);
And you'll be able to get all Payments objects that exist within your userID node.
I have a problem regarding the creation of an intent and the handover of an object with the getParcelableExtra() method to it.
The aim of the project is the creation of a recycler view. If an item from the recycler is selected a new intent gets started and should display more detailed data.
Because the data is fetched from an external MySQL DB I'm using Volley for most of the networking stuff.
The recycler is implemented inside the Volley onResponse() method which is first called at app start (onCreate). Until this point everything works fine and the recycler is loaded and displayed correctly.
public class UserAreaActivity extends AppCompatActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_area);
initializeRecycler();
}
public void initializeRecycler() {
operations.getFoodFromDB(getFoodID(), new IDatabaseOperations() {
#Override
public void onSuccess(final ArrayList<Food> food_list) {
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mLayoutmanager = new LinearLayoutManager(UserAreaActivity.this);
mAdapter = new FoodAdapter(food_list);
mRecyclerView.setLayoutManager(mLayoutmanager);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new FoodAdapter.OnItemClickListener() {
#Override
public void OnItemClick(int position) {
Intent intent = new Intent(UserAreaActivity.this, FoodProfile.class);
GETS CORRECT OBJECT----->intent.putExtra("food", food_list.get(position));
startActivity(intent);
}
});
}
});
}
}
As you see I created an interface for the Volley onResponse method called onSuccess. Inside this method I am creating an onItemClickListener and this is where it gets ugly.
The onItemClickListener opens up the more detailed view of the item, but the method getParcelableExtra() returns NULL. Whatever I do it never returns an object of the class Food.
public class FoodProfile extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(activity_food_profile);
Food food = getIntent().getParcelableExtra("food");<----RETURNS NULL
String price = food.getPrice();
String name = food.getName();
String rating = ((Float)food.getRating()).toString();
String imageRes = food.getmimgId();
TextView mPrice = (TextView) findViewById(R.id.Price);
mPrice.setText(price);
TextView mName = (TextView) findViewById(R.id.Name);
mName.setText(name);
TextView mRating = (TextView) findViewById(R.id.Rating);
mRating.setText(rating);
}
}
So the putExtra() works as intended and gets the correct object of the food class. But getParcelableExtra() returns NULL everytime. So no value is displayed in the started intent.
Food class:
public class Food implements Parcelable {
public int id;
public String name;
public String category;
public String date;
public int vegan;
public int vegetarian;
public String price;
public String uuid;
public float rating;
public String mimgId;
public Food(int id, String name, String category, int vegan, int vegetarian, String price, String uuid, float rating, String mimgId){
this.id = id;
this.name = name;
this.category = category;
this.date = date;
this.vegan = vegan;
this.vegetarian = vegetarian;
this.price = price;
this.uuid = uuid;
this.rating = rating;
this.mimgId = mimgId;
}
protected Food(Parcel in) {
id = in.readInt();
name = in.readString();
category = in.readString();
date = in.readString();
vegan = in.readInt();
vegetarian = in.readInt();
price = in.readString();
uuid = in.readString();
rating = in.readFloat();
mimgId = in.readString();
}
public static final Creator<Food> CREATOR = new Creator<Food>() {
#Override
public Food createFromParcel(Parcel in) {
return new Food(in);
}
#Override
public Food[] newArray(int size) {
return new Food[size];
}
};
public int getId() {
return id;
}
public String getName() {
if(name != null) {
name = name.replaceAll(System.getProperty("line.separator"), (""));
}
return name;
}
public String getDate() {
return date;
}
public int isVegan() {
return vegan;
}
public int isVegetarian() {
return vegetarian;
}
public String getPrice() {
return price;
}
public String getUuid() {
return uuid;
}
public float getRating(){return rating;}
public String getmimgId() {
return mimgId;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(price);
dest.writeString(name);
dest.writeString(((Float)rating).toString());
dest.writeString(mimgId);
}
}
Has anyone an idea whats causing the getParcelableExtra() to return null?
Thanks for your help in advance!
As I commented above, the writeToParcel() is problematic. The parcel should be written and read in the same order.
Please refer to the following pages as reference:
What is Parcelable in android
Using Parcelable
Understanding Androids Parcelable - Tutorial