How i can in this code
#Override
protected void onStart() {
super.onStart();
//if the user is already signed in
//we will close this activity
//and take the user to profile activity
if (mAuth.getCurrentUser() != null) {
finish();
startActivity(new Intent(this, ActivitySplash.class));
}
}
make check whether the child (userId) is set to ON / OFF and if ON then we run the code
if (mAuth.getCurrentUser() != null) {
finish();
startActivity(new Intent(this, ActivitySplash.class));
}
if OFF then we show a specific activity.
My database
As #FrankvanPuffelen said, you should spend some time reading docs, it would help you write code yourself, still I am briefing the things for you here. It should make things more clear.
Reading from database is done by correctly referencing your desired node from the database and then using the correct eventListener. There are 3 types of eventListeners present, singleValueEventListener, valueEventListener and childEventListener.
Read more about each of them in detail in docs.
This answer can also help you understand childEventListeners.
To retrieve the value of status node you have to go sequentially through your database parent nodes, that are users and that uid with value nfe....
So in code it would look something like this:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("users").child(uid);
// uid has the value nfe...
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String status = dataSnapshot.child("status").getValue(String.class);
// compare the value of status here and do what you want
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "onCancelled", databaseError.toException());
}
});
Related
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).
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();
I have one question, every time i want to insert data, it is replacing the old data either from another email as well, and when i go and change that line ref.child("User01").setValue(user); user01 to user02 then it is generating another user, so can u plz tell me how i resolve that issue......... , so that from one email i can create one user and when i login from other user, it will automatically create another user.
public void btnInsert(View view) {
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
getValues();
ref.child("User01").setValue(user);
Toast.makeText(EditableProfileActivity.this,"Data Inserted Successfully......", Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
public void btnLogout(View view) {
firebaseAuth.signOut();
finish();
startActivity(new Intent(this, MainActivity.class));
}
You'll typically store the user data in the database under each user's UID (which is guaranteed to be unique for each user).
If your user variable points to a Firebase Authentication User then this can be done with:
ref.child(user.getUid()).setValue(user);
I have a firebase database from which I save and retrieve data from, to and from. I know how datasnapshot works inside an addValueEventListener. The problem is that this is only called or triggered when the firebase database detects change in its data. I only want to access data and read it to be able to store it in an arraylist or the same thing.
I have a code like this:
public void foo(){
DatabaseReference x= FirebaseDatabase.getInstance().getReference().child("x");
reservations.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String userID = client.getId();
for(DataSnapshot snap : dataSnapshot.getChildren()){
if(snap.child("someId").equals(someId)) number++;
if(snap.child("userID").getValue().equals(client.getId())){
isAlreadyReserved = true; // if user has already reserved the item
alreadyReserved();
break;
}
Log.e("isAlreadyReserved: ", isAlreadyReserved+"");
numberOfReservations++;
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
if(isAlreadyReserved) {
alreadyReserved();
}
else if(number == numberOfCopies){
// material is no longer available
OtherActivity.showMaterialUnavailable();
}
else{
Reservation reservation = new Reservation();
reservation.setBookId(this.bookId);
reservation.setResID((numberOfReservations+1)+"");
reservation.setUserID(client.getId());
String key = reservations.push().getKey();
reservations.child(key).setValue(reservation);
Log.e("Reservations: ", "reserve successful");
AlertDialog.Builder builder = new AlertDialog.Builder(this.context);
builder.setTitle(R.string.reservationSuccess_title)
.setMessage(R.string.reservationSuccess_body);
AlertDialog dialog = builder.create();
dialog.show();
}
}
You can see that inside onDataChange I only count materials and set some flags, which I can supposedly do outside the ValueEventListener.
But I notice that this is faulty because onDataChange is called only when writing to the Firebase database occurs. Which should not be the case.
What can I do to loop through the values inside the DatabaseReference x without calling onDataChange, or without using DataSnapshot?
You cannot loop inside a DatabaseReference without using a listener. When we are talking about Firebase, we are talking only about listeners. So in order to get those values, you need to use a listener and than get the data out from the dataSnapshot.
What i think your problem is in your case, is that onDataChange method is called in an asynchronously way. This means that everything you are doing outsite this method is actually executed before onDataChange method has been called. So in order to understand what is actually going on, please see this post and this post. Reading this posts, will teach you how to query data in Firebase and how to retrieve data from Firebase asynchronously.
Hope it helps.
In order to get the values of DatabaseReference x, you should use addListenerForSingleValueEvent
x.addListenerForSingleValueEvent(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
//do something
}
#Override
public void onCancelled(DatabaseError databaseError)
{
//do something
}
});
as mentioned in the firebase documentation:
public void addListenerForSingleValueEvent (ValueEventListener
listener)
Add a listener for a single change in the
data at this location. This listener will be triggered once with the
value of the data at the location.
Im trying to save user information in Firebase Database but a strange behavior happens that make the Save button to restart the same activity not the Intent that i made for the next activity .
public void userData () {
user.setFName(Fname.getText().toString());
user.setLName(Lname.getText().toString());
user.setEmail(Email.getText().toString());
user.setAddress(userAddress.getText().toString());
user.setPassword(UserInfo.getString("Password", ""));
user.setID(CicID.getText().toString());
user.setUsername(Usnm.getText().toString());
if (bAdmn.isChecked()) user.setMajor("Business Administrator");
if (BTech.isChecked()) user.setMajor("Business Tech");
if (masscom.isChecked()) user.setMajor("Mass Com");
if (Eng.isChecked()) user.setMajor("Engineering");
final String us = user.getUsername();
Log.i("Username", us);
MyDatabase1.child("USERS").child(us).setValue(user);
Intent i = new Intent(getApplicationContext() , chooseCoursesActivity.class);
startActivity(i);
}
that is the method for save button , Note that i want to update the user information in a profile Activity if the user wants to change his First name or Last name or something .
But after Clicking save button , the data is saved correctly but the intent never done . it recreate the same Activity .
in the Login activity there is aLogin button which checks username and password then attempt to log in based on data ,if login successful it goes to that Profile Activity .
Save button in Profile Activity re Do the method in Login button in Login Activity which checks everything and goes to Profile Activity which what causing the Re Create Problem .
Here is the code for login button :
MyDatabase = FirebaseDatabase.getInstance().getReference();
MyDatabase.child("USERS").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
boolean exists = false;
for (DataSnapshot child : dataSnapshot.getChildren()) {
final Map<String, Object> model = (Map<String, Object>) child.getValue();
if (model.get("username").equals(Username.getText().toString())) {
exists = true;
Log.i("USername"," Correct");
if(exists){
MyDatabase.child("USERS").orderByChild("username").equalTo(Username.getText().toString())
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child :dataSnapshot.getChildren()){
Log.i("Password",child.getValue().toString());
Log.i( "Password",child.child("password").toString());
if(password.getText().toString().equals(child.child("password").getValue())){
Log.i("LOGIN","Success");
loginsuccessful = true ;
if(loginsuccessful){
saveCredntials(Username.getText().toString(),password.getText().toString());
Intent i2 = new Intent(getApplicationContext(), ProfileActivity.class);
i2.putExtra("loginStats",IsLoggedIn);
i2.putExtra("Username",Un);
i2.putExtra("Password",Pw);
startActivity(i2);
finish();}
}else{
Log.i("LOGIN","Failed");
loginsuccessful= false ;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(getApplicationContext(),"Error",Toast.LENGTH_LONG).show();
}
});
}
break;
}else {
Log.i("LOGIN","FAiled");
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Sorry for making this too long but i dont know the problem .
I just solved this problem! According to your case, please avoid using addValueEventListener, because it will listen to all changes you make to the database. That's why every time you make any change to the database, the code in the addValueEventListener (startActivity) will be executed no matter you call that login function or not.
My suggestion is using addListenerForSingleValueEvent instead of addValueEventListener (Make sure you change ALL the addValueEventListener in your Android project to addListenerForSingleValueEvent), or you can even remove the listener if you don't really need it. I don't know if it is a good design, but it should be able to solve your problem.
Avoid putting startActivity on a firebase listener. startActivity execute every time a value is added or removed from firebase database.