Firebase Value Event listener being skipped - android

When debugging, the program doesn't get into user ref value event listener why would this happen?
I get rid = null but the firebase instantiation is correct from what I can tell.
[text so stack overflow lets me post since there's too much code and no further explanation for the issue]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.send_message_chat);
getSupportActionBar().hide();
String userID = FirebaseAuth.getInstance().getCurrentUser().getUid();
useref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot snap : snapshot.getChildren()) {
rid = snap.child("receiverid").getValue(String.class);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
rv = findViewById(R.id.rvcahtitems);
b = findViewById(R.id.chatsendb);
field = findViewById(R.id.chatfield);
user = FirebaseAuth.getInstance().getCurrentUser();
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String msg = field.getText().toString();
if ((!msg.equals("")))
{
SendM(user.getUid(), rid, msg);
}
else
{
Toast.makeText(ChatScreen.this, "Can't send an empty message", Toast.LENGTH_SHORT);
}
field.setText("");
}
});
rv.setLayoutManager(new LinearLayoutManager(this));
readmsgs(userID, rid);
}

Related

Not able to retrieve data from Firebase real time database in Android studio

I'm new to the firebase and android studio. I'm working on a project in which I have to fetch details of the current user and display the name. It is throwing "user doesn't exist' toast even if I'm logged in I'm attaching everything below. Maybe I have done some mistakes please let me know.
Code to fetch details of the current user
public class Succesfully_sign_up extends AppCompatActivity {
DatabaseReference reff;
TextView name;
Button signout;
FirebaseUser curr_user;
String curr_user_str;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_succesfully_sign_up);
name = findViewById(R.id.name);
curr_user=FirebaseAuth.getInstance().getCurrentUser();
if(curr_user!=null)
{
curr_user_str = curr_user.getUid();
reff = FirebaseDatabase.getInstance().getReference("userdetails");
reff.child(curr_user_str).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
HelperClass data = dataSnapshot.getValue(HelperClass.class);
if (data != null) {
name.setText(data.getFullname_hc());
} else {
Toast.makeText(Succesfully_sign_up.this, "User does't exist", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
else
{
startActivity(new Intent(Succesfully_sign_up.this,student_signup.class));
}
}
}
My HelperClass
public class HelperClass {
String fullname_hc,amizone_id_hc,mobile_num_hc,email_id_hc;
public HelperClass()
{
}
public HelperClass(String fullname_hc, String amizone_id_hc, String mobile_num_hc, String email_id_hc) {
this.fullname_hc = fullname_hc;
this.amizone_id_hc = amizone_id_hc;
this.mobile_num_hc = mobile_num_hc;
this.email_id_hc = email_id_hc;
}
public String getFullname_hc() {
return fullname_hc;
}
public void setFullname_hc(String fullname_hc) {
this.fullname_hc = fullname_hc;
}
public String getAmizone_id_hc() {
return amizone_id_hc;
}
public void setAmizone_id_hc(String amizone_id_hc) {
this.amizone_id_hc = amizone_id_hc;
}
public String getMobile_num_hc() {
return mobile_num_hc;
}
public void setMobile_num_hc(String mobile_num_hc) {
this.mobile_num_hc = mobile_num_hc;
}
public String getEmail_id_hc() {
return email_id_hc;
}
public void setEmail_id_hc(String email_id_hc) {
this.email_id_hc = email_id_hc;
}
}
I think you have created the database manually, your user id 8448.... is not generated by the Firebase android, so it is showing that error. If not then please share the code of creation of that above database structure.
How about looping through the children and accessing data:
//the reference
reff = FirebaseDatabase.getInstance().getReference("userdetails");
//the reading
reff.child.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//loop through every possible child under "userdetails"
for(DataSnapshot ds : dataSnapshot.getChildren()){
String fullName = ds.child("fullname_hc").getValue(String.class);
name.setText(fullName);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});

In Android Studio, retrieving Data from Firebase does not work

When running the app the data is not retrieved but when debugging i can see where it is in terms of the database link.
When it runs and get to addValueEventListener, it doesn't go into the function which is pretty weird, don't know if this is because its async or not but either way data from Firebase does not get retrieved.
public GarbageItems(int itemNum) {
String itemId = String.valueOf(itemNum);
database = FirebaseDatabase.getInstance();
gameObjectRef = database.getReference().child("gameObjects");
itemInformationGrabber(gameObjectRef, itemId);
}//GarbageItems(Constructor)
private void itemInformationGrabber(DatabaseReference gameObjectRef, String itemId) {
DatabaseReference dataReference = gameObjectRef.child(itemId);
DatabaseReference itemColor = dataReference.child("Color");
itemColor.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange( DataSnapshot dataSnapshot) {
String color = dataSnapshot.getValue(String.class);
setColor(color);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
This is in a different classs that calls GarbageItem
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
colorTextView = findViewById(R.id.ColorTextView);
itemTextView = findViewById(R.id.ItemNameTextView);
GarbageItems garbageItems = new GarbageItems(1);
Color = garbageItems.getColor();
}
try this...
private void itemInformationGrabber(DatabaseReference gameObjectRef, String itemId) {
DatabaseReference dataReference = gameObjectRef.child(itemId);
DatabaseReference itemColor = dataReference.child("Color");
itemColor.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange( DataSnapshot dataSnapshot) {
for(Datasnapshot dataSnap : dataSnapshot.getChildren()){
String color = dataSnap.child("Color").getValue(String.class);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Hope it helps you :)

Trying to replace a data from specific child (Firebase Database)

I want to replace kids/[id]/kidLimit/[new data]
So what I do is I make a spinner with kidName data, then with the selected item from that spinner I want to replace the data of kidLimit (with the same parent as the selected item from the spinner).
The first thing I do is to find the unique key of the selected item, then go to the kidLimit with that unique key to then use the setValue() method.
public class setLimit extends AppCompatActivity {
private DatabaseReference db;
private EditText etLimit;
private Button btnSetLimit;
private Spinner kidSpinner;
private String kidKey;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_limit);
etLimit = findViewById(R.id.et_limit);
btnSetLimit = findViewById(R.id.btn_confirm);
kidSpinner = findViewById(R.id.spinner_kid);
//PUTTING STRING LIST FROM FIREBASE TO SPINNER DROPDOWN STARTS HERE
db = FirebaseDatabase.getInstance().getReference().child("kids");
db.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
final List<String> kid = new ArrayList<>();
for (DataSnapshot dataSnapshot1: dataSnapshot.getChildren()) {
String kidName = dataSnapshot1.child("kidName").getValue(String.class);
kid.add(kidName);
}
ArrayAdapter<String> kidNameAdapter = new ArrayAdapter<>(setLimit.this, android.R.layout.simple_spinner_item, kid);
kidNameAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
kidSpinner.setAdapter(kidNameAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//ENDS HERE
//ONCLICKLISTENER
btnSetLimit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
findId();
String newLimit = etLimit.getText().toString().trim();
db.child(kidKey).child("kidLimit").setValue(newLimit);
}
});
}
//FINDING KEY FROM THE SELECTED SPINNER ITEM
public void findId(){
String kidName = kidSpinner.getSelectedItem().toString();
db = FirebaseDatabase.getInstance().getReference().child("kids");
db.orderByChild("kidName").equalTo(kidName).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
kidKey = dataSnapshot1.getKey();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
So basically what I did was using the snapshot inside the onclick method to find the key. But when I check them on the log, it showed that the kidkey variable is null the first time I press the button, but after that it's not null anymore.
What can I to do so when I press the button, I can go to a specific child to replace it's data without getting any null pointer exception?
Here's the database that I use
When you do this
btnSetLimit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
findId();
String newLimit = etLimit.getText().toString().trim();
db.child(kidKey).child("kidLimit").setValue(newLimit);
}
});
findId(); is executed but you don't know when it will finish, so after that method is executed and waiting for data, this line
db.child(kidKey).child("kidLimit").setValue(newLimit);
will have kidKey with a null value because it has not been pulled yet from the database, so instead, you should move your code to the onDataChange() or make a new callback when all the asynchronous process finishes
btnSetLimit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
findId();
}
});
public void findId(){
String kidName = kidSpinner.getSelectedItem().toString();
String newLimit = etLimit.getText().toString().trim();
db = FirebaseDatabase.getInstance().getReference().child("kids");
db.orderByChild("kidName").equalTo(kidName).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
kidKey = dataSnapshot1.getKey();
}
db.child(kidKey).child("kidLimit").setValue(newLimit);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});

How to prevent android studio from skipping activities?

I have a quiz app that will save the score on firebase. It works properly. But whenever I try to retake the quiz, it will just show the first activity, and then skip all the activity after it and proceed to the final activity where it shows the output. I checked everything, the IDs are all unique. I can't find where I went wrong.
This is the first part of my quiz. When I retake the quiz, the scores will reset to 0. It works properly. But when I click next, it will just proceed to the final activity where the output is shown.
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_part1);
firebaseAuth = FirebaseAuth.getInstance();
firebaseDatabase = FirebaseDatabase.getInstance();
phqChoice1 = (RadioButton) findViewById(R.id.phqChoice1);
phqChoice2 = (RadioButton) findViewById(R.id.phqChoice2);
phqChoice3 = (RadioButton) findViewById(R.id.phqChoice3);
phqChoice4 = (RadioButton) findViewById(R.id.phqChoice4);
btnNext = (Button) findViewById(R.id.btnNext);
getAnswer();
final DatabaseReference myRef = firebaseDatabase.getReference(firebaseAuth.getUid()).child("test");
if (myRef != null) {
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
HashMap<String, Object> result = new HashMap<>();
result.put("anx", 0);
result.put("dep", 0);
myRef.updateChildren(result);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getMessage());
}
});
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
UserHistory userHistory = new UserHistory();
userHistory.setAnx(anx);
userHistory.setDep(dep);
myRef.setValue(userHistory);
Intent myIntent = new Intent(Part1.this, Part2.class);
startActivity(myIntent);
finish();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
System.out.println("Entering data failed. " + databaseError.getMessage());
}
});
}
});
}}
private void getAnswer() {
radioGroup1 = (RadioGroup) findViewById(R.id.radioGroup1);
radioGroup1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == R.id.phqChoice2) {
dep++;
} else if (checkedId == R.id.phqChoice3) {
dep = dep + 2;
} else if (checkedId == R.id.phqChoice4) {
dep = dep + 3;
}
}
});}
This is the part2 activity where android skips these activities and will just proceed to the final activity if I retake the quiz.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_part2);
firebaseAuth = FirebaseAuth.getInstance();
firebaseDatabase = FirebaseDatabase.getInstance();
btnNext = (Button)findViewById(R.id.btnPart2);
DatabaseReference myRef = firebaseDatabase.getReference(firebaseAuth.getUid()).child("test");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
UserHistory userHistory = dataSnapshot.getValue(UserHistory.class);
anxHistory = userHistory.getAnx();
depHistory = userHistory.getDep();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(Part2.this, databaseError.getCode(), Toast.LENGTH_SHORT).show();
}
});
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getAnswer();
anxValue = anxHistory + anx;
final DatabaseReference myRef = firebaseDatabase.getReference(firebaseAuth.getUid()).child("test");
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
HashMap<String, Object> result = new HashMap<>();
result.put("anx", anxValue);
myRef.updateChildren(result);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getMessage());
}
});
Intent part3A = new Intent(Part2.this, Part3.class);
startActivity(part3A);
}
});
}
private void getAnswer() {
radioGroup2 = (RadioGroup) findViewById(R.id.radioGroup2);
int selectedItem = radioGroup2.getCheckedRadioButtonId();
if (selectedItem == R.id.part2Choice2) {
anx++ ;
} else if (selectedItem == R.id.part2Choice3) {
anx = anx + 2 ;
}
else if (selectedItem == R.id.part2Choice4) {
anx = anx + 3;
}else {
anx = 0;
}
}
}
I expect the output to proceed as normally whenever I retake the quiz again. All activities should proceed as usual and no activity should be skipped. What actually happens is the first activity is working properly but all the other activities that are related to the quiz ends up being skipped. Please help. I am clueless and I don't know what else should I check.
In addition, if I click the radio button A (value is 0), the activity will just continue as usual. If I click other buttons which has a value that is greater than 0, (Value is 1-3), and then the activity will just skip to the final activity wherein the output is displayed.
To simplify: Click Radio button A (0) > Next activity, Click Radio Button A(0), > Next Activity (Proceeds as normal.). OR Click Radio button B (1) > Skips other activity, proceeds to the final activity.
try to put the Intent outside the btnNext,onClickListener method
Intent part3A = new Intent(Part2.this, Part3.class);
btnNext.setOnClcikListener(){
//here call your intent from Part2
startActivity(part3A);
}
I put the intent activity inside the ValueEventListener so whenever I try to enter new data, it will skip to the Final activity. The fix:
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
UserHistory userHistory = new UserHistory();
userHistory.setAnx(anx);
userHistory.setDep(dep);
myRef.setValue(userHistory);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
System.out.println("Entering data failed. " + databaseError.getMessage());
}
});
Intent myIntent = new Intent(Part1.this, Part2.class);
startActivity(myIntent);
finish();

onClick update to firebase database not working

I'm trying to update the identity value of the user with onClick method of the update button but it is not working and no value is being updated.
Here is my activity (I used the Query to get to the user unique ID):
public class Update extends AppCompatActivity {
EditText identity;
DatabaseReference ref;
Button update;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_check);
update = (Button) findViewById(R.id.button_update);
identity = (EditText) findViewById(R.id.edit_text_identity);
mStorageRef = FirebaseStorage.getInstance().getReference("uploads");
String key = getIntent().getExtras().get("androidId").toString();
final Query userQuery = FirebaseDatabase.getInstance().getReference().child("Users").orderByChild("androidId");
userQuery.equalTo(key).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot foodSnapshot: dataSnapshot.getChildren()) {
final String userUID = foodSnapshot.getKey();
ref = FirebaseDatabase.getInstance().getReference().child(userUID);
identity.setText(getIntent().getStringExtra("identity"));
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ref.child("identity").setValue("noo");
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
}
);
}
}
My database structure is like:
{
"Users" : {
"uid1" : {
"name" : "Josh",
"identity": "yes"
},
"uid2" : {
"name" : "June",
"identity": "no"
}
}
}
And there is no error showing in the logcat. What might be the problem here?
The problem here is that the ref you've used is not pointing exactly to the node you want to be updated. You can use this to do so:
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference().child("Users").child(uidYouWant);
rootRef.child("identity").setValue("noo");
}
});
Also to get the uidYouWant instead of using query you can go though all the nodes to get the one you want, using orderByChild() and equalTo() directly like this:
ref.orderByChild("androidID").equalTo(key).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot data: dataSnapshot.getChildren()){
// do what you want to
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});

Categories

Resources