how do you remove an object in firebase without removing entire "simnumbers" child ? for example only remove "LAkUUug..."
First, As per your comment you need to get autogenerated key.For that :-
public String keyval;
FirebaseDatabase.getInstance().getReference().child("numbers-guess-...").child("simnumbers").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot != null && dataSnapshot.getValue() != null) {
// for (DataSnapshot child : dataSnapshot.getChildren()) {
// if we want to get do operation in multiple data then write your code here
// }
keyval = dataSnapshot.getKey());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
//add code in case you not get proper dat from firebase
}
});
To remove value in firbase you need to use removeValue() and as per my view you should use it with addOnCompleteListener().
Now, add that keyval as a key which you want to remove. show below code:-
FirebaseDatabase.getInstance().getReference()
.child("simnumbers").child(keyval).removeValue()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
//enter your code what you want excute after remove value in firebase.
} else {
//enter msg or enter your code which you want to show in case of value is not remove properly or removed failed.
Toast.makeText(this, "Remove Failed", Toast.LENGTH_SHORT).show();
}
}
});
For deleting you have to use removeValue() method. You have to know the key value of the child otherwise u cant do it. lets say somehow you managed to get the key value which node you want to delete. then just write the code .
FirebaseDatabase.getInstance().getReference().child("simnumbers").child("LAkUUug.....").removeValue();
Related
Reading the documentation, It seems childEventListener does not fire when the path does not exist.
This is a problem since I want to display a message to the user that there is no data.
I could add a valueEventListener like in this answer but I'm limiting the query to the latest value i.e query.limitToLast() and a valueEventListener doesn't limitTolast but gets all the data in the path.
Example, I have:
posts
{
$userid
{
$postid {
post_content:content
timestamp:1234567
}
$postid {
post_content:content
timestamp:1234567
}
$postid {
post_content:content
timestamp:1234567
}
$postid {
post_content:content
timestamp:1234567
}
}
}
I'm only interested in the latest post so I do firebaseRef.child(users).child(userid).limitToLast(1).addChildEventListener but the user might not have posts yet and childEventListener does not fire in that case.
If you want to handle both the children and the case where no children exists, you can add both a value and a child listener:
Query query = firebaseRef.child(users).child(userid).limitToLast(1);
query.addChildEventListener(new ChildEventListener() {
void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
...
}
...
});
query.addValueEventListener(new ValueEventListener() {
void onDataChange(DataSnapshot snapshot) {
if (!snapshot.exists()) {
// TODO: handle the "no data available" scenario
}
});
});
The Firebase client is smart enough to only load data once, even if there are multiple listeners like in the above case.
If you want, you can also accomplish this with a single ValueEventListener like this:
query.addValueEventListener(new ValueEventListener() {
void onDataChange(DataSnapshot snapshot) {
if (!snapshot.exists()) {
// TODO: handle the "no data available" scenario
}
else {
for (DataSnapshot childSnapshot: snapshot.getChildren()) {
// TODO: handle the child snapshot
}
}
});
});
Since we now get all matching child nodes in snapshot, we loop over the snapshot.getChildren() to get the same data as in onChildAdded.
Since its impossible to attach a listener to a non existing path, you could try adding a property to your user that sets the number of posts he has. Add a listener to that property and if it changes, then you are certain that indeed the user has a path reference in posts, then you can add a listener to that node and get the query every time a child is added with .childAdded .
I'm implementing a search in my android app and I can't seem to make it work.
public void loadReleaseData(String name) {
mDatabase.child("releases")
.child("europe")
.child("data").orderByChild("game/name").startAt(name)
.endAt(name+"\uf8ff")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChildren()) {
Log.d(TAG, "New datasnapshot");
for (DataSnapshot data : dataSnapshot.getChildren()) {
_Release release = data.getValue(_Release.class);
if (release != null) {
// No platform filter set add all releases!
list.add(release);
if (release.getGame() != null) {
Log.d(TAG, "NAME: " + release.getGame().getName());
}
}
mUpcomingGamesAdapter.notifyDataSetChanged();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
When I remove startAt or endAt either of the two data is shown but not the correct data, but when they're both added in, nothing is show and my log "New datasnapshot" doesn't even get printed. I'm searching on the names of the games I have in my database.
My firebase database:
According to your comments, the reason your code was not working was because the value of the name variable that was passed to startAt() and endAt methods was incorrect.
The key for solving the problem is to pass as an argument to both method the exact same name that exist in the database, in this case you should search the name in lower case.
I have some trouble trying to check if user information is stored already in the FireBase database.
Basically I'm trying to do something stupid like this:
"select user_name from user where user_id="+userID+"
And if the nickname exists it should make the boolean var isFirstTime = false and if it doesn't it should stay true. And after that it should show register box or not.
This is my db:
Firebase
And this is my code in onCreate method:
databaseReference = FirebaseDatabase.getInstance().getReference();
DatabaseReference dbRefFirstTimeCheck = databaseReference.child("User").child(user.getUid()).child("Nickname");
isFirstTime = true;
dbRefFirstTimeCheck.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.getValue() != null) {
isFirstTime=false;
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
if(isFirstTime) {
showNewUserBox();
}
else {
}
No matter what I do, the methor showNewUserBox() is being called. How do I get the data i need and check if it's there?
As others have commented, data is loaded from Firebase asynchronously. By the time you check isFirstTime, the data hasn't been loaded yet, onDataChange hasn't been run yet, so ifFirstTime will have its default value (false for a boolean).
All code that requires data from the database should be inside onDataChange (or invoked from within there). The simplest fix for your code is:
databaseReference = FirebaseDatabase.getInstance().getReference();
DatabaseReference dbRefFirstTimeCheck = databaseReference.child("User").child(user.getUid()).child("Nickname");
dbRefFirstTimeCheck.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
showNewUserBox();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Also see some of the many questions about asynchronous loading from Firebase, such as getContactsFromFirebase() method return an empty list (or this quite old classic: Setting Singleton property value in Firebase Listener).
Reading the documentation, It seems childEventListener does not fire when the path does not exist.
This is a problem since I want to display a message to the user that there is no data.
I could add a valueEventListener like in this answer but I'm limiting the query to the latest value i.e query.limitToLast() and a valueEventListener doesn't limitTolast but gets all the data in the path.
Example, I have:
posts
{
$userid
{
$postid {
post_content:content
timestamp:1234567
}
$postid {
post_content:content
timestamp:1234567
}
$postid {
post_content:content
timestamp:1234567
}
$postid {
post_content:content
timestamp:1234567
}
}
}
I'm only interested in the latest post so I do firebaseRef.child(users).child(userid).limitToLast(1).addChildEventListener but the user might not have posts yet and childEventListener does not fire in that case.
If you want to handle both the children and the case where no children exists, you can add both a value and a child listener:
Query query = firebaseRef.child(users).child(userid).limitToLast(1);
query.addChildEventListener(new ChildEventListener() {
void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
...
}
...
});
query.addValueEventListener(new ValueEventListener() {
void onDataChange(DataSnapshot snapshot) {
if (!snapshot.exists()) {
// TODO: handle the "no data available" scenario
}
});
});
The Firebase client is smart enough to only load data once, even if there are multiple listeners like in the above case.
If you want, you can also accomplish this with a single ValueEventListener like this:
query.addValueEventListener(new ValueEventListener() {
void onDataChange(DataSnapshot snapshot) {
if (!snapshot.exists()) {
// TODO: handle the "no data available" scenario
}
else {
for (DataSnapshot childSnapshot: snapshot.getChildren()) {
// TODO: handle the child snapshot
}
}
});
});
Since we now get all matching child nodes in snapshot, we loop over the snapshot.getChildren() to get the same data as in onChildAdded.
Since its impossible to attach a listener to a non existing path, you could try adding a property to your user that sets the number of posts he has. Add a listener to that property and if it changes, then you are certain that indeed the user has a path reference in posts, then you can add a listener to that node and get the query every time a child is added with .childAdded .
I want to check if the bus number already exists in the database of Firebase.
Here's my sample code. I've been searching for the past days but I can't find the right code to do so.
ref = new Firebase(Config.FIREBASE_URL);
postRef = ref.child("BusNumber");
busNum = edtBus.getText().toString().trim();
route1 = route.trim();
seat = edtSeat.getText().toString().trim();
if (!busNum.isEmpty() && !route1.isEmpty() && !seat.isEmpty()) {
postRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child(busNum).exists()) {
edtBus.setError("Bus number already exists.");
edtBus.setText("");
} else {
busNumber = new BusNumber();
busNumber.setBusNum(busNum);
busNumber.setRoute(route1);
busNumber.setNumSeat(seat);
postRef.push().setValue(busNumber);
edtBus.setText("");
edtSeat.setText("");
Toast.makeText(AddBusActivity.this, "Saving successful!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Toast.makeText(AddBusActivity.this, "Error", Toast.LENGTH_SHORT).show();
Toast.makeText(AddBusActivity.this, firebaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} else {
Toast.makeText(AddBusActivity.this, "Please complete the information", Toast.LENGTH_SHORT).show();
}
Can somebody help me with this matter? Thanks in advance.
Whether the if statement is correct or not, also my problem is why does the postRef.addListenerForSingleValueEvent...doesn't work? I tried to test some toast message but the message won't pop out.
Your approach is wrong.
When you are doing this dataSnapshot.child(busNum).exists(), it's looking for the busNum in the key section, where your keys are -kasajdh....
So instead what you can do is, get the iterable, now when you look for
data.child(busNum).exists() it relates to the value
postRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot data: dataSnapshot.getChildren()){
if (data.child(busNum).exists()) {
//do ur stuff
} else {
//do something if not exists
}
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Rather than getting whole iterable list of data, you can query for exact entry.
postRef = FirebaseDatabase.getInstance().getReference().child("BusNumber");
postRef.orderByChild("busNum").equalTo(busNum)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
//bus number exists in Database
} else {
//bus number doesn't exists.
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
dataSnapshot.child(busNum).getValue() != null
should work.
It is difficult to guess the problem because you do not show how busNum and busNumber are defined and managed. Is busNumber a String?
push() creates a reference to an auto-generated child location. The auto-generated key looks something like -KPB_cS74yoDaKkM9CNB.
The statement postRef.push().setValue(busNumber) stores value busNumber in location BusNumber/<push-generated-key>.
The statement dataSnapshot.child(busNum).exists() tests for the existence of a value at location BusNumber/<busNum>. It will not be true unless busNum is one of the keys created by push().
It's not clear how you want your data structured. If your bus numbers are Strings and are unique, you do not need to generate a key with push(). You could store the existence of bus numbers using:
postRef.child(busNumber).setValue(true)
if(!(dataSnapshot.child("Users").child(busNum).exists()))
and then hashmap object