I have this code which retrieves the information I need from the firebase database:
private void getname(){
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Query lastQuery = ref.child("ride_info").orderByKey().limitToLast(1);
lastQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()){
String value0_float = ds.child("pickup").child("name").getValue(String.class);
pickupName = String.valueOf(value0_float);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
and i have this:
public String getPickupName() {
getname();
String s = String.valueOf(pickupName);
return s;
}
All of the above code is in the RideObject class.
This is the code there is in CardRequestAdapter Class to display the String in the textview mPickupName:
public View getView(int position, View convertView, ViewGroup parent){
RideObject card_item = getItem(position);
if (convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item__card_request, parent, false);
}
TextView mDistance = convertView.findViewById(R.id.distance);
TextView mTime = convertView.findViewById(R.id.time);
CircularProgressBar mProgressBar = convertView.findViewById(R.id.circularProgressBar);
mDistance.setText(card_item.getPickupName());
mTime.setText(card_item.getCalculatedTime() + " min");
final Handler ha=new Handler();
ha.postDelayed(new Runnable() {
#Override
public void run() {
//call function
card_item.setTimePassed(card_item.getTimePassed() + (float)0.5);
mProgressBar.setProgress(card_item.getTimePassed());
if(card_item.getTimePassed() > 100){
items.remove(card_item);
notifyDataSetChanged();
}
ha.postDelayed(this, 50);
}
}, 50);
return convertView;
}
}
The problem I have is that I cannot get the name I got from the Firebase database. Why is nothing displayed in the text view?
Data is loaded from Firebase asynchronously, since it may take some time. If you set some breakpoints or add some logging you'll likely see that mDistance.setText(card_item.getPickupName()); runs before pickupName = String.valueOf(value0_float), which means you're setting an empty string into the text view.
The rule to fix/prevent this is simple: any code that needs data from the database needs to be inside onDataChange or be called from there.
So something like:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Query lastQuery = ref.child("ride_info").orderByKey().limitToLast(1);
lastQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()){
String value0_float = ds.child("pickup").child("name").getValue(String.class);
pickupName = String.valueOf(value0_float);
mDistance.setText(pickupName);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});
Also see:
getContactsFromFirebase() method return an empty list
Related
I am making an android app with Firebase Realtime Database. This is my database:
{
"Data" : {
"UyhzVqsz1BVFKoePa2NEmlPFu382" : {
"Budget_Income" : {
"bbbb" : {
"stData1" : "bbbb",
"stData2" : "bb",
"stData3" : "bb",
"stData4" : "1000"
}
},
"Entry_Income" : {
"bbbb" : {
"-MYk3lQuK4X6zcIZtHRD" : {
"stData1" : "bbbb",
"stData2" : "20 Apr 2021",
"stData3" : "ddd",
"stData4" : "500"
}
}
}
}
}
}
I am trying to get the data back in RecyclerView in one activity with the following reference:
myfire = FirebaseDatabase.getInstance();
myRef = myfire.getReference().child("Data").child(strUID).child("Entry_Income");
String uid = myRef.child(title).push().getKey(); // title is reference to "bbb"
myRef.child(uid).addValueEventListener(new ValueEventListener() {
..........................
The data is empty.
I am able to get one child by the following code:-
myRef = myfire.getReference().child("Data").child(strUID).child("Entry_Income").child(title);
myRef.child("-MYk3lQuK4X6zcIZtHRD").addValueEventListener(new ValueEventListener() {
.............
But I want all children like "-MYk3lQuK4X6zcIZtHRD" in my RecyclerView.
My Issue I think the reference to push id is wrong.
A solution with example needed.
full code*
myRef = myfire.getReference().child("Data").child(strUID).child("Budget_Income");
//-------------------------------
//------------------------------------------
Toast.makeText(MainActivity.this, "Please Wait a While !", Toast.LENGTH_LONG).show();
//-------------------------
options1 = new FirebaseRecyclerOptions.Builder<category>()
.setQuery(myRef, category.class)
.build();
final FirebaseRecyclerAdapter<category, holder1> adapter = new FirebaseRecyclerAdapter<category, holder1>(options1) {
#SuppressLint("SetTextI18n")
#Override
protected void onBindViewHolder(#NotNull final holder1 holder, final int i, #NotNull final category passage) {
final String title = getRef(i).getKey();
category=title;
assert title != null;
myRef = myfire.getReference().child("Data").child(strUID).child("Budget_Income");
myRef.child(title).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() == null) {
Toast.makeText(getApplicationContext(), "Data Not Available", Toast.LENGTH_LONG).show();
} else {
final String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
final String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
final String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
final String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();
category basic = new category(stData1, stData2, stData3, stData4);
holder.tvOne.setText(stData1);
holder.tvTwo.setText(stData4);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
myRef = myfire.getReference().child("Data").child(strUID).child("Entry_Income").child(title);
String uid = myRef.push().getKey();
assert uid != null;
myRef.child(uid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() == null) {
Toast.makeText(getApplicationContext(), "Data Not Available", Toast.LENGTH_LONG).show();
} else {
final String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
final String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
final String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
final String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();
category basic = new category(stData1, stData2, stData3, stData4);
holder.tvThree.setText(stData3);
holder.tvFour.setText(stData4);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
}
#NonNull
#Override
public holder1 onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item1, parent, false);
return new holder1(v);
}
};
userlist.setAdapter(adapter);
adapter.startListening();
}
}
Category Class code*
public class category {
private String stData1;
private String stData2;
private String stData3;
private String stData4;
public category() {
}
public category(String stData1, String stData2, String stData3, String stData4) {
this.stData1 = stData1;
this.stData2 = stData2;
this.stData3 = stData3;
this.stData4 = stData4;
}
public String getStData1() {
return stData1;
}
public void setStData1(String stData1) {
this.stData1 = stData1;
}
public String getStData2() {
return stData2;
}
public void setStData2(String stData2) {
this.stData2 = stData2;
}
public String getStData3() {
return stData3;
}
public void setStData3(String stData3) {
this.stData3 = stData3;
}
public String getStData4() {
return stData4;
}
public void setStData4(String stData4) {
this.stData4 = stData4;
}
}
This is the way to get the data:
myRef = myfire.getReference().child("Data").child(strUID).child("Entry_Income").child(title);
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
String value = data.child("stData4").getValue(String.class);
}
holder.tvThree.setText(value);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});
But the problem is that recycler view is showing more items at bottom without values on scroll.
According to my last comment, please see below a solution for getting data from the following reference:
rootRef -> Data -> strUID -> Entry_Income
No matter if there is a single child ("bbbb"), or multiple children under the "Entry_Income" node and Log the data of stData1 out in the logcat. You can similarly do the same thing for the other stData2, stData3, stData4 fields. So please try the code below:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference entryIncomeRef = rootRef.child("Data").child(uid).child("Entry_Income");
entryIncomeRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot titleSnapshot : task.getResult().getChildren()) {
for (DataSnapshot categorySnapshot : titleSnapshot.getChildren()) {
category cat = categorySnapshot.getValue(category.class);
Log.d(TAG, cat.getStData1());
}
}
} else {
Log.d(TAG, task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
The key for solving this issue is to loop through the "DataSnapshot" object twice, using a call to ".getChildren()" method. However, this solution will only work if you create your own adapter. It won't work with the "FirebaseRecyclerAdapter". If you need to use the Firebase-UI library, then I recommend you duplicate the data by adding all "bbbb" children into a single node. This practice is called "denormalization" and it's a common practice when it comes to Firebase. For a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Database.
That being said, create a new reference to the newly created node, and pass that object to the FirebaseRecyclerOptions.Builder's "setQuery()" method. That's it!
I think the data at that point indeed empty. Try setting a value with that "new id" and then add your listener.
myfire = FirebaseDatabase.getInstance();
myRef = myfire.getReference().child("Data").child(strUID).child("Entry_Income");
String uid = myRef.child(title).push().getKey(); // title is reference to "bbb"
//note that this line edited: we are setting a value for the "new" key
myRef.child(uid).setValue(yourData);
myRef.child(uid).addValueEventListener(new ValueEventListener() {
...
}
I am listing my data with using firebase realtime database in my application. These data are constantly updated.
But when the data is updated ones time in firebase, the second of the same data is formed in my application. Listing data increases by 1 with each update.
I mean;
There is 1 piece of data in firebase realtime database and when that data is updated it continues to appear same data as 2-3-4-5-6.
Here is my code:
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
trackItems = new ArrayList<Track>();
adapter = new TracksAdapter(this, trackItems);
myListView.setAdapter(adapter);
myListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long arg3) {
pos = position;
myListView.setItemChecked(position, true);
}
});
final ValueEventListener trackListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
Track track = dataSnapshot.getValue(Track.class);
track.setId(dataSnapshot.getKey());
trackItems.add(0, track);
myListView.setItemChecked(0, true);
refreshList();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
shortWarnToast("Veriler yüklenirken bir hata oluştu.");
}
};
ValueEventListener user_tracksListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
trackItems.clear();
pos = -1;
Iterable<DataSnapshot> user_trackChildren = dataSnapshot.getChildren();
for (DataSnapshot track : user_trackChildren) {
String key = track.getKey();
mDatabaseReference.child("/tracks/" + key).addValueEventListener(trackListener);
}
refreshList();
}
#Override
public void onCancelled(DatabaseError databaseError) {
shortWarnToast("Veriler yüklenirken bir hata oluştu.");
}
};
My code is as below... I am new to this line so any help is appreciated.
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<Contacts> options = new FirebaseRecyclerOptions.Builder<Contacts>().setQuery(ChatsRef, Contacts.class).build();
FirebaseRecyclerAdapter<Contacts, ChatsViewHolder> adapter = new FirebaseRecyclerAdapter<Contacts, ChatsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final ChatsViewHolder holder, int position, #NonNull Contacts model) {
final String usersIDs = getRef(position).getKey();
final String[] retImage = {"default_image"};
UsersRef.child(usersIDs).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
if (dataSnapshot.hasChild("image")) {
retImage[0] = dataSnapshot.child("image").getValue().toString();
Picasso.get().load(retImage[0]).into(holder.profileImage);
}
final String retName = dataSnapshot.child("name").getValue().toString();
holder.userName.setText(retName);
if (dataSnapshot.child("userState").hasChild("state")) {
String state = dataSnapshot.child("userState").child("state").getValue().toString();
if (state.equals("online")) {
holder.onlineIcon.setVisibility(View.VISIBLE);
}
else if (state.equals("offline")) {
holder.onlineIcon.setVisibility(View.INVISIBLE);
}
}
else {
holder.onlineIcon.setVisibility(View.INVISIBLE);
}
// i am having trouble from this portion onwards
final String[] retLastMessage = {null};
final String[] retLastMessageTime = {null};
final String[] retLastMessageDate = {null};
RootRef.child("Contacts").child(currentUserID).child(usersIDs).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("LastMessage")) {
retLastMessage[0] = dataSnapshot.child("LastMessage").getValue().toString();
retLastMessageTime[0] = dataSnapshot.child("LastMessageTime").getValue().toString();
retLastMessageDate[0] = dataSnapshot.child("LastMessageDate").getValue().toString();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
holder.userLastMessage.setText(retLastMessage[0]);
String retLastMessageTimeDate = retLastMessageTime[0] + " " + retLastMessageDate[0];
holder.userLastMsgTime.setVisibility(View.VISIBLE);
holder.userLastMsgTime.setText(retLastMessageTimeDate);
//upto this I guess
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent chatIntent = new Intent(getContext(), ChatActivity.class);
chatIntent.putExtra("visit_user_id", usersIDs);
chatIntent.putExtra("visit_user_name", retName);
chatIntent.putExtra("visit_image", retImage[0]);
startActivity(chatIntent);
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#NonNull
#Override
public ChatsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.users_display_layout, viewGroup, false);
return new ChatsViewHolder(view);
}
};
chatsList.setAdapter(adapter);
adapter.startListening();
}
app is crashing when it tries to retrieve these data from firebase
please help. I am using the above code to actually get the final message and time of last message to display it in chats fragment of my app. the last message and last message time are saved in contacts node
this is how the database entry looks like
So you need to do that :
DatabaseReference reference =
FirebaseDatabase.getInstance().getReference("Contacts").child("2").child("3");
// of course you are not going to use 2 and 3 as a child but it's just to illustrate my point
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
after changing the code a little the app ran smoothly
the changed code is:
final String[] retLastMessage = {null};
final String[] retLastMessageTime = {null};
final String[] retLastMessageDate = {null};
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Contacts").child(currentUserID).child(usersIDs);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("LastMessage")) {
retLastMessage[0] = dataSnapshot.child("LastMessage").getValue().toString();
retLastMessageTime[0] = dataSnapshot.child("LastMessageTime").getValue().toString();
retLastMessageDate[0] = dataSnapshot.child("LastMessageDate").getValue().toString();
holder.userLastMessage.setVisibility(View.VISIBLE);
holder.userLastMessage.setText(retLastMessage[0]);
String retLastMessageTimeDate = retLastMessageTime[0] + " " + retLastMessageDate[0];
holder.userLastMsgTime.setVisibility(View.VISIBLE);
holder.userLastMsgTime.setText(retLastMessageTimeDate);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
rest of the code remains same. the problem was i was assigning values after the ValueEventListener. i don't know the proper reason but aster assigning the values inside the ValueEventLister the code seems to run fine.
I am just having a problem when populating my list view. I think I know what's the problem since I tested it multiple times and it seems like the path for retrieving my data is actually the user store and not the bets but I don't seem to get where does the path come from. I was looking back at the methods and it seems that the path would be the DatabaseReference although my reference in the class is just standard
mDatabase = FirebaseDatabase.getInstance().getReference();
Here is my Adapter
public class CustomAdapter extends BaseAdapter{
Context c;
ArrayList<Bets> bets;
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); //Getting currently logged user
DatabaseReference mDatabase;
String hours;
String samount;
public CustomAdapter(Context c, ArrayList<Bets> bets) {
this.c = c;
this.bets = bets;
}
#Override
public int getCount() {
return bets.size();
}
#Override
public Object getItem(int pos) {
return bets.get(pos);
}
#Override
public long getItemId(int itemid) {
return itemid;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
if(view == null)
{
view = LayoutInflater.from(c).inflate(R.layout.item_layout,viewGroup,false);
}
TextView condition = (TextView) view.findViewById(R.id.conditionList);
TextView place = (TextView) view.findViewById(R.id.placeList);
TextView amount = (TextView) view.findViewById(R.id.amountList);
final Bets bet = (Bets) this.getItem(position);
condition.setText(bet.getCondition());
place.setText(bet.getPlace());
String setamount = String.valueOf(bet.getAmount());
amount.setText(setamount);
hours = String.valueOf(bet.getHours());
samount = String.valueOf(bet.getAmount());
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openDetailList(bet.getCreator(),bet.getCondition(),bet.getPlace(),hours,samount,bet.getJoined(),bet.getCreatorUid(),bet.getJoinedUid());
}
});
return view;
}
public void openDetailList(String...details)
{
Intent i = new Intent(c, ListDetail.class);
i.putExtra("CREATOR_KEY",details[0]);
i.putExtra("CONDITION_KEY",details[1]);
i.putExtra("PLACE_KEY",details[2]);
i.putExtra("HOURS_KEY",details[3]);
i.putExtra("AMOUNT_KEY",details[4]);
i.putExtra("JOINED_KEY",details[5]);
i.putExtra("CREATORUID_KEY",details[6]);
i.putExtra("JOINEDUID_KEY",details[7]);
c.startActivity(i);
}
}
and here is my FirebaseHelper
public class FirebaseHelper {
DatabaseReference db;
Boolean saved = null;
ArrayList<Bets> bets = new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
public Boolean save(Bets bets)
{
if(bets == null)
{
saved = false;
}
else {
try {
db.child("bets").push().setValue(bets);
saved = true;
} catch (DatabaseException e) {
e.printStackTrace();
saved = false;
}
}
return saved;
}
private void fetchData(DataSnapshot dataSnapshot)
{
bets.clear();
for(DataSnapshot snapshot: dataSnapshot.getChildren())
{
Bets bet = snapshot.getValue(Bets.class);
bets.add(bet);
}
}
public ArrayList<Bets> retrieve()
{
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "onComplete: Failed=" + databaseError);
}
});
return bets;
}
}
Saving/Inserting data works perfectly fine since I even have a sample data to show you after I added a bet but it doesn't populate the data.
{
"bets" :
{
"-LAzYM9SA-8Sg0YgGqnv" :
{
"amount" : 10,
"condition" : "It will be sunny",
"creator" : "Ginart",
"creatorUid" : "MxQPvCjUIkahVSZk1y2stdCxeY32",
"hours" : 2,
"joined" : "Free",
"joinedUid" : "",
"place" : "New York"
}
For some reason I think it reads the users data which is here
"users" : {
"EbYtfLUPs7Vu2rvnExaOaqJ4J883" : {
"balance" : 5,
"bets" : 1
},
Since every time I add a new user, the list view adds an Item to my list but with no data at all just my template and Android Studio shows me this
W/ClassMapper: No setter/field for balance found on class Models.Bets
W/ClassMapper: No setter/field for bets found on class Models.Bets
So it must be something wrong with the paths in my opinion. My Bets Model has no balance and bets variables.
Here is my OnCreate method where I'm using the retrieve() method in firebase
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logged_in);
Money = (EditText) findViewById(R.id.Balance);
User = (EditText) findViewById(R.id.Player);
betList = (ListView) findViewById(R.id.BetList);
addbet = (FloatingActionButton) findViewById(R.id.AddBet);
addcreds = (TextView) findViewById(R.id.addCredits);
Money.setInputType(0);
User.setInputType(0);
betting = FirebaseDatabase.getInstance().getReference();
mDatabase = FirebaseDatabase.getInstance().getReference();
helper = new FirebaseHelper(betting);
mDatabase.child("users").child(current.getUid().toString()).child("balance").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
balance = dataSnapshot.getValue(Long.class);
String b = String.valueOf(balance);
Money.setText(b);
}
#Override
public void onCancelled(DatabaseError error) {
Money.setText("Error");
}
});
mDatabase.child("users").child(current.getUid().toString()).child("bets").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
bets = dataSnapshot.getValue(Long.class);
}
#Override
public void onCancelled(DatabaseError error) {
}
});
User.setText(current.getDisplayName().toString());
//ADAPTER
adapter = new CustomAdapter(this,helper.retrieve());
betList.setAdapter(adapter);
addbet.setOnClickListener(this);
addcreds.setOnClickListener(this);
}
Also, whenever I'm trying to change my reference to
betting = FirebaseDatabase.getInstance().getReference().child("bets");
I get this error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: app.betme.betme, PID: 22814
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Long to type Models.Bets
at com.google.android.gms.internal.zg.zzb(Unknown Source)
at com.google.android.gms.internal.zg.zza(Unknown Source)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
at Utils.FirebaseHelper.fetchData(FirebaseHelper.java:67)
at Utils.FirebaseHelper.access$000(FirebaseHelper.java:21)
at Utils.FirebaseHelper$1.onChildAdded(FirebaseHelper.java:81)
at com.google.android.gms.internal.px.zza(Unknown Source)
at com.google.android.gms.internal.vj.zzHX(Unknown Source)
at com.google.android.gms.internal.vp.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
It's not error, It's just a waring from Firebase that you should have methods to set data for balance and bets
I am trying to retrieve firebase data using addValueEventListener, but unfortunately i am not be able to get right data.
I have New_Deal_List.java class, and in this class i want to retrieve `public class New_Deal_List extends AppCompatActivity {
ListView lvDealList;
List<NewDeal_Database> dealList;
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("Expert");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new__deal__list);
lvDealList = (ListView)findViewById(R.id.lvDealList);
dealList = new ArrayList<>();
}
#Override
protected void onStart() {
super.onStart();
rootRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dealList.clear();
for(DataSnapshot dealSnapshot : dataSnapshot.getChildren()){
NewDeal_Database info = dealSnapshot.getValue(NewDeal_Database.class);
dealList.add(info);
}
DealList adapter = new DealList( New_Deal_List.this,dealList);
lvDealList.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(New_Deal_List.this,"Databse error",Toast.LENGTH_SHORT).show();
}
});
}
I am adding data through New_Deal.java by this method
private void AddNewDeal(){
int DealName = Integer.parseInt(etDealName.getText().toString());
String NewDealCategory = etNewDealCategory.getText().toString();
String DishName = etDishName.getText().toString();
String DealDescription = etDealDescription.getText().toString();
if(TextUtils.isEmpty(etDishName.getText().toString()) || TextUtils.isEmpty(etNewDealCategory.getText().toString()) || TextUtils.isEmpty(etDishName.getText().toString()) || TextUtils.isEmpty(etDealDescription.getText().toString())){
Toast.makeText(this,"All fileds must be filled.",Toast.LENGTH_SHORT).show();
}else{
DealId = keyRefrence.push().getKey();
//firebaseDatabase data = new firebaseDatabase(DealName,NewDealCategory,DishName,DealDescription);
//Contact_Info info = new Contact_Info( DealName, NewDealCategory, DealDescription);
NewDeal_Database info = new NewDeal_Database(DealName,NewDealCategory, DishName, DealDescription); keyRefrence.child(Cooker_Deal).child(DealId).child(Deal).setValue(info);
Toast.makeText(this,"Information Added",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(New_Deal.this,New_Deal_Time.class);
startActivity(intent);
}
}
I am setting value using this NewDeal_Databse.java
public NewDeal_Database(int DealName,String NewDealCategory, String DishName, String DealDescription){
this.DealName = DealName;
this.NewDealCategory = NewDealCategory;
this.DishName = DishName;
this.DealDescription = DealDescription;
}
public int getDealName() {
return DealName;
}
public String getNewDealCategory() {
return NewDealCategory;
}
public String getDishName() {
return DishName;
}
public String getDealDescription() {
return DealDescription;
}
Also i DealList.java for array adapter
public class DealList extends ArrayAdapter <NewDeal_Database> {
private Activity context;
private List<NewDeal_Database> dealList;
public DealList(Activity context, List<NewDeal_Database> dealList){
super(context, R.layout.list_layout, dealList);
this.context = context;
this.dealList = dealList;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View listViewItem = inflater.inflate(R.layout.list_layout,null,true);
TextView tvDealName = (TextView)listViewItem.findViewById(R.id.tvDealNamelayout);
TextView tvNewDealCategory = (TextView)listViewItem.findViewById(R.id.tvNewDealCategorylayout);
NewDeal_Database info = dealList.get(position);
tvDealName.setText(String.valueOf(info.getDealName()));
tvNewDealCategory.setText(info.getNewDealCategory());
return listViewItem;
}
}
I get these on values on output
Output the data
I this is firebase databse snapshot
firebase datasbe snapshot
updated firebase databse snapshot
Updated output
Problem solved using this code:
#Override
protected void onStart() {
super.onStart();
//dealList.clear();
rootRef.child(id).child(Cooker_Deal).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dealSnapshot : dataSnapshot.getChildren()){
for(DataSnapshot datas : dealSnapshot.getChildren()){ //
NewDeal_Database info = datas.getValue(NewDeal_Database.class);
count++;
if(count>3){
dealList.add(info);
count=0;
}
}
}
DealList adapter = new DealList( New_Deal_List.this,dealList);
lvDealList.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
I think its nested too much but to answer your question, you need to remove this from your code:
dealList.clear();
and add it outside of the addValueEventListener()
like this:
protected void onStart() {
super.onStart();
dealList.clear();
rootRef.addValueEventListener(new ValueEventListener() {
Edit:
#Override
protected void onStart() {
super.onStart();
dealList.clear();
rootRef.child(expertId).child("Cooker Deals").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dealSnapshot : dataSnapshot.getChildren()){
for(DataSnapshot datas : dealSnapshot.getChildren(){
NewDeal_Database info = datas.getValue(NewDeal_Database.class);
dealList.add(info);
}
DealList adapter = new DealList( New_Deal_List.this,dealList);
lvDealList.setAdapter(adapter);
adapter.notifydatasetchanged();
}
Assuming that faum-expert nide is a direct child of your Firebase database, to get that data, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = rootRef.child("faum-expert").child("Expert").child(expertId).child("Cooker Deals");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String dealName = ds.child("Deals Information").child("dealName").getValue(String.class);
String newDealCategory = ds.child("Deals Information").child("newDealCategory").getValue(String.class);
Log.d("TAG", dealName + " / " + newDealCategory);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
ref.addListenerForSingleValueEvent(eventListener);
The output will be:
4567 / kagj
But pay atention, the fields inside your model class are first letter uppercase and in your database are first letter lowercase. To solve this, add the following annotations in front of your fields like this:
#PropertyName("dealName")
private String DealName;
#PropertyName("newDealCategory")
private String NewDealCategory;
#PropertyName("dishName")
private String DishName;
#PropertyName("dealDescription")
private String DealDescription;