Firebase Database on Android - orderByChild not working - java

I am new in Firebase and that's my first App using Firebase.
My App got 15 different Scores and I separate them with a Spinner. Each time a different score is selected, it shoult be re-sorted.
It works, it always shows the correct scores but not Ordered.
Database:
My Code:
FirebaseDatabase database;
DatabaseReference databaseReference;
Query myQuery;
database = FirebaseDatabase.getInstance();
databaseReference = database.getReference().getRef().child("Users");
for (int i = 0; i < spinner.getCount(); i++) {
int x = i+1;
if (i == spinner.getSelectedItemPosition()) {
prefsEdit.putInt("selectedScore", x).apply();
myQuery = databaseReference.orderByChild("score"+possibleScores.get(i));
downloadScores();
break;
}
}
public void downloadScores() {
myQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
users.clear();
for (DataSnapshot post : dataSnapshot.getChildren()) {
Users user = post.getValue(Users.class);
users.add(user);
}
UsersList scoreAdapter = new UsersList(HighscoreActivity.this, users);
scoreList.setAdapter(scoreAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
And that's my result. For example Score 6
I tried to use this too
myQuery = databaseReference.child(firebaseAuth.getUid()).child("highscores").orderByChild("score"+possibleScores.get(i));
and got this error:
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Long to type com.example.user.app.Users
So what I overlook?
Thanks a lot

Related

How to sort data from Firebase realtime database?

I'm using GraphView library. My code below gets data from Firebase real-time database and updates the graph with values from database, but it isn't sorted. I need it to be sorted in ascending order in X axis. The data in X axis is Long type, then it's converted to date.
I've tried adding dp[index] to array list and using different sorting methods, but nothing seems to work.
#Override
public void onStart() {
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
FirebaseAuth auth;
auth = FirebaseAuth.getInstance();
FirebaseUser user = auth.getCurrentUser();
String id = user.getUid();
DataPoint[] dp = new DataPoint[(int) snapshot.child(id).getChildrenCount()];
int index = 0;
for(DataSnapshot myDataSnapshot : snapshot.child(id).getChildren()){
PointValue pointValue = myDataSnapshot.getValue(PointValue.class);
dp[index] = new DataPoint(pointValue.getxValue(), pointValue.getyValue());
index ++;
}
lineGraphSeries.resetData(dp);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
super.onStart();
}
AlertDialog, where data is being written to the database:
builder.setPositiveButton("ADD",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
if(TextUtils.isEmpty(weightEditText.getText().toString()) || TextUtils
.isEmpty(dateEditText.getText().toString())) {
Toast.makeText(getActivity(),"Please provide weight and date",
Toast.LENGTH_SHORT).show();
} else{
linearLayout.addView(createNewTextView(weightEditText.getText().toString(),
dateEditText.getText().toString()));
String id = user.getUid();
String randomId = reference.push().getKey();
try {
Date date = sdf.parse(dateEditText.getText().toString());
long x = date.getTime();
int y = Integer.parseInt(weightEditText.getText().toString());
PointValue pointValue = new PointValue(x,y);
reference.child(id).child(randomId).setValue(pointValue);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
});
builder.setView(view);
builder.show();
PointValue class:
public class PointValue {
long xValue;
int yValue;
public PointValue() {
}
public PointValue(long xValue, int yValue) {
this.xValue = xValue;
this.yValue = yValue;
}
public long getxValue() {
return xValue;
}
public int getyValue() {
return yValue;
}
}
#EDIT
Thanks to #Frank van Puffelen, I've managed to sort my data from Firebase Database using orderByChild()
https://firebase.google.com/docs/database/android/lists-of-data#sort_data
below working solution:
#Override
public void onStart() {
FirebaseAuth auth;
auth = FirebaseAuth.getInstance();
FirebaseUser user = auth.getCurrentUser();
String id = user.getUid();
Query dateAscendingOrder = database.getReference("users")
.child(id).orderByChild("xValue");
dateAscendingOrder.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
DataPoint[] dp = new DataPoint[(int) snapshot.getChildrenCount()];
int index = 0;
for (DataSnapshot myDataSnapshot : snapshot.getChildren()){
PointValue pointValue = myDataSnapshot.getValue(PointValue.class);
dp[index] = new DataPoint(pointValue.getxValue(), pointValue.getyValue());
index++;
}
lineGraphSeries.resetData(dp);
}

How to create condition inside the datasnapshot/recyclerview in Android Studio?

I created tabbed activity for my project. I have three tabs which are Paid , Unpaid and Item Posted
I want to classify every of them based on the status. I have created the coding but I'm not sure on how to implement the method inside my coding. I want only order that have "PAID" as their status will be shown up inside my PaidFrag.
PaidFrag:
databaseReference = FirebaseDatabase.getInstance().getReference("Order");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
orderList = new ArrayList<>();
for (DataSnapshot orderSnapshot : dataSnapshot.getChildren()) {
for (DataSnapshot ds : orderSnapshot.getChildren()) {
Order order = ds.getValue(Order.class);
if (order.getStatus().equals("UNPAID")) ;
orderList.add(ds.getValue(Order.class));
}
}
psOrderAdapter PsOrderAdapter = new psOrderAdapter(orderList);
recyclerView.setAdapter(PsOrderAdapter);
}
}
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, final int i) {
myViewHolder.name.setText("Name : " + orderList.get(i).getName());
myViewHolder.status.setText("Status : " + orderList.get(i).getStatus());
myViewHolder.total.setText("Total Price : RM " + orderList.get(i).getTotal());
myViewHolder.address.setText("Address : " + orderList.get(i).getAddress());
myViewHolder.dateTime.setText("Order ID :" + orderList.get(i).getOrder_id());
myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String cust_id = orderList.get(i).getCust_id();
String oid = orderList.get(i).getOrder_id();
String status = orderList.get(i).getStatus();
String courier = orderList.get(i).getCourier();
String track = orderList.get(i).getTrackingNum();
String num = orderList.get(i).getPhone();
Intent intent = new Intent(context, updateStatus.class);
intent.putExtra("cust_id",cust_id);
intent.putExtra("order_id",oid);
intent.putExtra("status",status);
intent.putExtra("courier", courier);
intent.putExtra("trackingNum",track);
intent.putExtra("phone",num);
context.startActivity(intent);
}
});
It sounds like you're looking for a Firebase Database query, which limits what nodes are returns from the database:
databaseReference = FirebaseDatabase.getInstance().getReference("Order");
Query query = databaseReference.orderByChild("status").equalTo("PAID");
query.addValueEventListener(new ValueEventListener() {
...
You'll need to make sure that the status and PAID strings match the exact key and value that you have in your database.
For more on this, see the Firebase documentation on ordering and filtering data.

retreiving sqlite and firebase data at the same time

Im retrieving a UID from sqlite and using that uid to fetch data from firebase but the problem is its only fetching the values of the first UID and not after that
Code
String userId = null;
Cursor csr = myDBHlpr.getAllQuestions4();
while (csr.moveToNext()) {
userId = csr.getString(csr.getColumnIndex(KEY_USER_ID));
}
final String uid = userId;
mUsersDatabase.child(userId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mName = dataSnapshot.child("Name").getValue().toString();
String mStatus = dataSnapshot.child("Status").getValue().toString();
String mDisplayImage = dataSnapshot.child("Image").getValue().toString();
mUsers.add(new IdHelper(mName, mStatus, mDisplayImage));
mAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The table has multiple rows with different UIDs and firebase too has multiple UID data... I have crosschecked multiple times. But still only the one item is fetched. Why is that? should i retrieve sqlite data is a string []?
Database ref is perfect and the problem according to me is that im fetching only one data as userid and im thinking it stops there so only one IDs data is getting fetched from firebase. Anyways can someone help me out please
Edit
public Cursor getAllQuestions4() {
return this.getWritableDatabase().query(TABLE_ID_DATA,null,null,null,null,null,null);
}
I guess your problem is the while loop. You are only using the last userId. So change your code as follows (please notice the change of the last bracket of your while loop):
String userId = null;
Cursor csr = myDBHlpr.getAllQuestions4();
while (csr.moveToNext())
{
userId = csr.getString(csr.getColumnIndex(KEY_USER_ID));
final String uid = userId;
mUsersDatabase.child(userId).addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mName = dataSnapshot.child("Name").getValue().toString();
String mStatus = dataSnapshot.child("Status").getValue().toString();
String mDisplayImage = dataSnapshot.child("Image").getValue().toString();
mUsers.add(new IdHelper(mName, mStatus, mDisplayImage));
mAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}

Firebase - how to enumerate all child values' contents?

I'm developing an Android app in Android Studio which lists events based on categories (music, sport, business, theatre). Every event has a name, description, location and time. This is how the events are stored in Firebase when a user posts events through my application:
How can I retrieve e.g. all childs and its contents in the Music category? I have four String arrays to display events (currently manually) like this:
String[] name = {"Eminem","Rihanna"};
String[] desc = {"Concert","Live Show"};
String[] location = {"Miami","Florida"};
String[] time = {"bllablla","bllablla"};
I want to populate the string arrays automatically from firebase, however I'm not sure how to get contents for every child element from Music element? If needed, I can post the Java code which populates the database as well.
Edit: I've tried this:
DatabaseReference info = FirebaseDatabase.getInstance().getReference("Events").child("Music");
info.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot val: dataSnapshot.getChildren()) {
// Retreive all Music childs and then retreive all data of them childs?
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
There is probably no easier solution than to download all of your music data, loop through all children and create corresponding arrays manually -
1) Create a class to map your firebase music record to -
class MusicRecord{
String date;
String eventDescription;
String eventName;
String location;
}
2) Load data, loop through children, retrieve MusicRecords and populate your arrays
protected void loadData(){
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Events").child("Music");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Iterable<DataSnapshot> recordsSnaphots = dataSnapshot.getChildren();
int count = (int) dataSnapshot.getChildrenCount();
int i = 0;
String[] names = new String[count];
String[] descriptions = new String[count];
String[] locations = new String[count];
String[] times = new String[count];
for(DataSnapshot recordSnapshot: recordsSnaphots){
MusicRecord record = recordSnapshot.getValue(MusicRecord.class);
if(record != null) {
names[i] = record.eventName;
descriptions[i] = record.eventDescription;
locations[i] = record.location;
times[i] = record.date;
i++;
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Based on your post, you'll have to do several things :
Create a model
You'll have to create a POJO that describes the structure of the data you have in your Firebase realtime database. In your case, create a class FirebaseEvent that has a Date and three Strings (eventDescription,eventName,location).
Instantiate your class
Based on your last snippet, instantiate your class with the data from your Firebase realtime database. Firebase API is still a bit tedious with this, but this is yet the most common way to do it
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
GenericTypeIndicator<HashMap<String,FirebaseEvent>> ti =
new GenericTypeIndicator<HashMap<String,FirebaseEvent>>() {};
HashMap<String,FirebaseEvent> retrievedEvents = childSnapshot.getValue(ti);
}
Now, what you have is a HashMap with keys like "Eminem" and "Rihanna" and the corresponding value that is a FirebaseEvent.
I choose to use an ArrayList for a dynamic data structure.
I also took a snapshot of my database:
public class MainActivity extends AppCompatActivity {
List<String> name= new ArrayList<String>();
List<String> location= new ArrayList<String>();
List<String> date= new ArrayList<String>();
private DatabaseReference mDatabase;
public static final String TAG= "YOUR-TAG-NAME";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDatabase = FirebaseDatabase.getInstance().getReference().child("Events").child("Music");
// Read from the database
mDatabase.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.
for (DataSnapshot values: dataSnapshot.getChildren()) {
//query for the parent of the date "Eminem"
String key = values.getKey().toString();
name.add(key);
//query for location in the music category
date.add(values.child("location").getValue().toString());
//query for date in the music category
date.add(values.child("date").getValue().toString());
}
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});
}
}

How to get string from firebase realtime db that contain in unique key

I want to get a string from this:
, but it has a unique key parent. How do I get string from db? I tried:
firebaseAuth = FirebaseAuth.getInstance();
fUID =firebaseAuth.getCurrentUser().getUid();
itemsUrl ="https://nextweaverproject.firebaseio.com/users/" + fUID ;
mDatabase = FirebaseDatabase.getInstance();
final DatabaseReference myRef = mDatabase.getReferenceFromUrl(itemsUrl);
myRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();
List<Object> values = new ArrayList<Object>(td.values());
strFb = new ArrayList<String>();
strFb.add(values.get(0).toString());
// strFb.add(urlLong);
Log.v("test"," " + strFb.get(strFb.size()-1));
}
But It returns all objects in db.
You can use child to get data from the database tree:
myRef.child("Scenes").child("Scene").("******").
(*****).addChildEventListener(new ChildEventListener() {
this way you should chain your fields.
You can use also addValueEventListener, addListenerForSingleValueEvent.
You can read about them here:
https://firebase.google.com/docs/database/android/retrieve-data
Thank you all. I found my solution by this:
myRef.child("Scenes").child("Scene").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot children : dataSnapshot.getChildren()) {
for (DataSnapshot child : children.getChildren()) {
//Log.v("key1"," " + child.getKey());
if(child.getKey().equals("Thumb")){
for (DataSnapshot child2 : child.getChildren()) {
//Log.v("key2"," " + child2.getValue(String.class));
for (DataSnapshot child3 : child2.getChildren()) {
//Log.v("key3"," " + child3.getKey());
if(child3.getKey().equals("LongUrl")){
Log.v("key4"," " + child3.getValue(String.class));
thumbUrl.add(child3.getValue().toString());
}
}
}
}
}
Log.v("keyResult"," " + thumbUrl);
// Log.v("key2"," " + thumbUrl);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Result here :Result

Categories