I've a database like this
"Node" : {
"Location_1" : {
"ID1" : {
"address" : "address1",
"balance" : "20",
"batch" : "xyz",
.
.
.
"studentID" : "ID1",
"studentName" : "Username",
"total" : "amount"
}
},
"Location_2" : {
"ID2" : {
"address" : "address2",
"balance" : "0",
"batch" : "xyz",
.
.
"studentID" : "ID2",
"studentName" : "username",
"total" : "amount"
}
}
"Location_3" : {
"ID3" : {
"address" : "address3",
"balance" : "0",
"batch" : "xyz",
.
.
"studentID" : "ID3",
"studentName" : "username",
"total" : "amount"
}
}
I'm able to check if the ID1 exists in a particular Location_1 using the code given below, but I'm unable to find if the ID1 exists across different Location_X id's.
String url = "https://firebaseURL/Node/";
url = url + Location_1;
databaseReference = FirebaseDatabase.getInstance().getReferenceFromUrl(url);
databaseReference.child(ID1).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
Toast.makeText(getApplicationContext(), "ID already present. Enter unique ID!", Toast.LENGTH_SHORT).show();
}
else { // not present, so go ahead and add
}
I tried using a function like this to check if the user is present in all the subNodes.
private boolean checkIfUserExists(String ID) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("Location_1");
.
.
String url = "https://firebaseURL/Node/";
databaseReference = FirebaseDatabase.getInstance().getReferenceFromUrl(url);
for(String s: arrayList){
if(getUserExists())
break;
databaseReference.child(s).child(ID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
setUserExists(true);
}
}
But always the function getUserExists return false. So I end up adding a new user in different location or updating the user's info in the same location.
Please let me know how to proceed on checking the existence of the userID in all the locationIDs
Related
I'm having trouble writing in my database because I have multiple unique ids that I don't know how to access.
I know that for writing I need to use something like this:
DatabaseReference ref=database.getReference().child("Children")
ChildData data = new ChildData(fullName,age);
ref.push().setValue(data);
My database looks like this:
{
"Children" : {
"55hxObZjRLY9PSZxZxGgSTRKzpc2" : {
"-MzUih5e40OsWPF_Dj0q" : {
"age" : "22",
"fullName" : "Cristina "
},
"plays" : {
"-MznnNih5fItYf2usXB4" : {
"centiseconds" : "70",
"currentDate" : "01.04.2022",
"currentHour" : "04:23:30",
"numberOfFails" : "5",
"seconds" : "2"
}
}
}
},
"Data" : {
"id1" : {
"centiseconds" : "70",
"currentDate" : "01.04.2022",
"currentHour" : "04:23:30",
"numberOfFails" : "5",
"seconds" : "2"
}
}
}
I need the "plays" child to be under "fullName" in "-MzUih5e40OsWPF_Dj0q", not as a separated child. How can I access the path without hardcoding it like this ref.child("MzUih5e40OsWPF_Dj0q").child("plays").push().setValue(data)? I will have multiple children in "Children" with different ids, I won't be able to harcode them.
Is there any function that returns the path for the unique id?
Here is the entire function:
public void writeNewData
(String fullName,String age) {
DatabaseReference reference = database.getReference().child("Data");
DatabaseReference ref=myRef.push();
ChildData data = new ChildData(fullName,age);
ref.push().setValue(data);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren()) {
DatabaseReference playRef=ref.child("plays");
DatabaseData databaseData = ds.getValue(DatabaseData.class);
playRef.push().setValue(databaseData);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
Edit: This is my desired schema:
{
"Children" : {
"55hxObZjRLY9PSZxZxGgSTRKzpc2" : {
"-MzUih5e40OsWPF_Dj0q" : {
"age" : "22",
"fullName" : "Cristina ",
"plays" : {
"-MznnNih5fItYf2usXB4" : {
"centiseconds" : "70",
"currentDate" : "01.04.2022",
"currentHour" : "04:23:30",
"numberOfFails" : "5",
"seconds" : "2"
}
}
},
}
},
"Data" : {
"id1" : {
"centiseconds" : "70",
"currentDate" : "01.04.2022",
"currentHour" : "04:23:30",
"numberOfFails" : "5",
"seconds" : "2"
}
}
}
If you want the plays information to be a sibling of the age and fullName properties, then you will need to have a plays field/property in your ChildData class.
You'll need two classes, one to represent a "play" and one to represent a "child". At its minimum these will look like:
public class Play {
public String centiseconds, currentDate, currentHour, numberOfFails, seconds;
}
public class Child {
public String age, fullName;
public Map<String, Play> plays = new HashMap<>();
}
If you read/write this class, you will get plays nested under the child's data.
I am trying to retrieve data from the Firebase Realtime Database and I only want where the category is equal to a String. For example, if my string is football then I should get all the data that has the category football in it. I run my app with the code I am about to show you but I get nothing but a blank page. I don't know what I am doing wrong.
databaseReference = FirebaseDatabase.getInstance().getReference();
if (Categories.InternetConnection.checkConnection(Categories.this)) {
databaseReference.child("Sports").orderByChild("category").equalTo("football")).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
myUploads.clear();
for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
for (DataSnapshot postsnapshot : userSnapshot.getChildren()) {
Model_Information upload = postsnapshot.getValue(Model_Information.class);
Collections.shuffle(myUploads);
myUploads.add(upload);
recyclerView.invalidate();
}
}
linearLayoutWithoutItems.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
aAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(Categories.this, databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});
Firebase Json
{
"MyStudents" : {
"KihlyfLkJMQ5uZWBDgLWNuBHKAE2" : {
"-MSr8HG6QCR2sO8MZHoM" : {
"category" : "Football",
"created" : "2-19-2021",
"name" : "Benny",
"time" : "2:47 AM",
"timestamp" : 1613684875762
},
"-MSr8awtvzrmm3P6A2LB" : {
"category" : "Basketball",
"created" : "2-19-2021",
"name" : "patrick",
"time" : "2:49 AM",
"timestamp" : 1613684960454,
},
"-MSr8mSn5OSTu5vdT4Wt" : {
"category" : "Football",
"created" : "2-19-2021",
"name" : "Shawn",
"time" : "2:50 AM",
"timestamp" : 1613685007616,
}
{
"MyStudents" : {
"WahlyfLkJMQ5uZWBDgLWNuBHKAE2" : {
"-MSr8HG6QCR2sO8MZHoM" : {
"category" : "Football",
"created" : "2-19-2021",
"name" : "Len",
"time" : "2:47 AM",
"timestamp" : 1613684875762
},
"JJr8awtvzrmm3P6A2LB" : {
"category" : "Basketball",
"created" : "2-19-2021",
"name" : "Armstrong",
"time" : "2:49 AM",
"timestamp" : 1613684960454,
},
"-JJr8mSn5OSTu5vdT4Wt" : {
"category" : "Football",
"created" : "2-19-2021",
"name" : "Bill",
"time" : "2:50 AM",
"timestamp" : 1613685007616,
}
The problem in your code lies in the fact that you are using an incorrect query:
databaseReference.child("Sports").orderByChild("category").equalTo("football"))
Assuming that MyStudents is a child right under your root node and the following statement:
if (Categories.InternetConnection.checkConnection(Categories.this)) { /* ... */ }
Returns true, please use the following query:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child(uid);
Query queryByCategory = uidRef.orderByChild("category").equalTo("Football");
queryByCategory.addValueEventListener(/* ... */);
Things to notice:
KihlyfLkJMQ5uZWBDgLWNuBHKAE2 is the UID of the logged-in user and should be added as a child in the reference.
The value of the category property is called "Football" and not "football", with lower-case "f".
Edit:
According to your last comment:
I'm not trying to just get their information I'm trying to get everyone that has students whose category is Football
There is no way you can achieve that using your actual database structure. The most simple solution I can think of is to create a new node that contains all Model_Information objects, no matter the user is. This practice is called denormalization and is 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.
Also, when you are duplicating data, there is one thing that needs to keep in mind. In the same way, you are adding data, you need to maintain it. In other words, if you want to update/delete an item, you need to do it in every place that it exists.
Here is the answer. Hopefully its helpful for someone :)
databaseReference = FirebaseDatabase.getInstance().getReference().child("MyStudents");
if (Categories.InternetConnection.checkConnection(Categories.this)) {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
myUploads.clear();
for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
for (DataSnapshot postsnapshot : userSnapshot.getChildren()) {
Model_Information upload = postsnapshot.getValue(Model_Information.class);
Collections.shuffle(myUploads);
if (upload.getCategory().equals("Football")) {
myUploads.add(upload);
}else{
Toast.makeText(Categories.this, "No results", Toast.LENGTH_LONG).show();
}
recyclerView.invalidate();
}
myUploads.add(upload);
recyclerView.invalidate();
}
}
aAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(Categories.this, databaseError.getMessage(), Toast.LENGTH_LONG).show();
}
});
{
"Mp6FLLdcSeXpfGPwP5i0ZBNZxd63" : {
"Age" : "20",
"Full name" : "Mike",
"Intent" : "Both",
"Reward" : "Nothing ",
"Variablex" : "one name",
"imageuri" : "images/Mp6FLLdcSeXpfGPwP5i0ZBNZxd63.jpeg"
},
"fWJcCPF16dUMKn1Sxz01VjF9Kgq2" : {
"Age" : "19",
"Full name" : "Other guy",
"Intent" : "Looking for help",
"Reward" : "nothing ",
"Variablex" : "one name",
"imageuri" : "images/fWJcCPF16dUMKn1Sxz01VjF9Kgq2"
}
}
This is my database. I want to get all the users with the same variablex. But i want only the id, the parent node. I want basically to build an array that contains all the ids of the users whose child value variablex is the same. And then use this array to call one user at a time get the id, perform other tasks with it etc.
public void othershit() {
Query qname3 = mDatabase.child("Variablex").orderByChild("Variablex").equalTo(userinput);
qname3.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
GenericTypeIndicator<List<String>> t = new GenericTypeIndicator<>();
List users = dataSnapshot.getValue(t);
textView8.setText(users.get(0).toString());
}
This is trigered with a button but everytime it crashes. Also i have three users with the same variablex. The structure is the same, this is a bit outdated version of my database but it is essentially the same.
Try using
dataSnapshot.getKey();
To retrieve the parent key of the found node which in your case is the FUID.
Edit -
Lets say your parent node for all the data is users
{
"users" :{
"Mp6FLLdcSeXpfGPwP5i0ZBNZxd63" : {
"Age" : "20",
"Full name" : "Mike",
"Intent" : "Both",
"Reward" : "Nothing ",
"Variablex" : "one name",
"imageuri" : "images/Mp6FLLdcSeXpfGPwP5i0ZBNZxd63.jpeg"
},
"fWJcCPF16dUMKn1Sxz01VjF9Kgq2" : {
"Age" : "19",
"Full name" : "Other guy",
"Intent" : "Looking for help",
"Reward" : "nothing ",
"Variablex" : "one name",
"imageuri" : "images/fWJcCPF16dUMKn1Sxz01VjF9Kgq2"
}
}
}
So here is what you need to do to get the list of all the ids which match the required
List<String> userIds = new Arraylist<>();
Query qname3 = mDatabase.child("users").child("Variablex").orderByChild("Variablex").equalTo(userinput)..addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
userIds.add(dataSnapshot.getKey());
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
This is how the json looks like
"Node" : {
"1-5-2018" : {
"10001" : {
"centre" : "centre_1",
"name" : "name_1",
"paidAmt" : "25000"
},
"10002" : {
"centre" : "centre_2",
"name" : "name_2",
"paidAmt" : "25000"
},
"10003" : {
"centre" : "centre_3",
"name" : "name_3",
"paidAmt" : "10000"
}
},
"2-5-2018 : {
"10004" : {
"centre" : "centre_4",
"name" : "name_4",
"paidAmt" : "20000"
}
}
I want to retrieve the values(centre, name and paidAmt) inside the given dates
I've tried using this particular query but it always shows data does not exist
Query query = databaseReference1.orderByKey().startAt(fromDate.getText().toString()).endAt(toDate.getText().toString());
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
Log.d(TAG, "Data exists within dates");
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Log.d(TAG , "Data are " + ds.getValue().toString());
}
}
else {
Log.d(TAG, "Data does not exist within dates");
}
}
Please let me know if it's possible to retrieve all the data within dates. In future i'm planning to add multiple data inside different dates and want to retrieve them based on requirement. Maybe monthly or weekly.
You are using timestamp instead of a date it may look like this.
"Node" : {
"1525188857" : {
"10001" : {
"centre" : "centre_1",
"name" : "name_1",
"paidAmt" : "25000"
},
"10002" : {
"centre" : "centre_2",
"name" : "name_2",
"paidAmt" : "25000"
},
"10003" : {
"centre" : "centre_3",
"name" : "name_3",
"paidAmt" : "10000"
}
},
"1525188873" : {
"10004" : {
"centre" : "centre_4",
"name" : "name_4",
"paidAmt" : "20000"
}
}
Fetch messages method
private void fetchMessages() {
rootRef.child("Messages").child(MessageSenderId).child(MessageRecieverId)
.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Messages messages = dataSnapshot.getValue(Messages.class);
messagesList.add(messages);
messageAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
Defining Ids
MessageSenderId = mAuth.getCurrentUser().getPhoneNumber();
MessageRecieverId = getIntent().getStringExtra("visit_user_id");
trying to make a basic chat app
Since only the senders id is called in rootref only the messages i send r being displayed in d recyclerview... im unable to receive messages because of this... how can i make it to retrieve recievers id and senders id also at the same time
Database strucutre
{
"Messages" : {
"+918105571584" : {
"+919945342730" : {
"-L58IPCLEeE21vH_-1Ry" : {
"message" : "Hi",
"seen" : false,
"time" : 1518427022478,
"type" : "text"
},
"-L58IU1VIHN0rHaUox3a" : {
"message" : "Hello",
"seen" : false,
"time" : 1518427042257,
"type" : "text"
},
"-L58IYN1GpHPdkWCY7Hn" : {
"message" : "Hi",
"seen" : false,
"time" : 1518427060021,
"type" : "text"
}
}
},
"+919945342730" : {
"+918105571584" : {
"-L58IPCLEeE21vH_-1Ry" : {
"message" : "Hi",
"seen" : false,
"time" : 1518427022478,
"type" : "text"
},
"-L58IU1VIHN0rHaUox3a" : {
"message" : "Hello",
"seen" : false,
"time" : 1518427042257,
"type" : "text"
},
"-L58IYN1GpHPdkWCY7Hn" : {
"message" : "Hi",
"seen" : false,
"time" : 1518427060021,
"type" : "text"
}
}
}
},
"Users" : {
"+918105571584" : {
"Email" : "",
"Name" : "Akash",
"Quote" : "",
"Status" : ""
},
"+919945342730" : {
"Email" : "",
"Name" : "Sav",
"Quote" : "",
"Status" : ""
}
}
}
According to your last comment, I understand that you can display only the messages that correpond to a single user. A user can see only his messages butd not other user messages. To solve this, you need to create chat rooms, in which every user can add messages that can be seen by all chat room members.
So for that, you need to change your database structure. You cannot achieve this, using the actual database.