I got problem with my app that i develop using Android Studio and Firebase.
I want to get data from firebase and compare it with another data from firebase and show it in a listview.
The data that i want, is the string in the follow image.
The problem here is, I dont know how to get multiple string from the database.
This is the code that i having been trying:
public class testActivity extends AppCompatActivity {
private DatabaseReference applydatabase;
String app;
String applied;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
app = getIntent().getExtras().getString("id");
applydatabase = FirebaseDatabase.getInstance().getReference().child("Apply").child(app).child("Applyid");
applydatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
applied = dataSnapshot.getValue().toString();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
You can use DataSnapshot.getChildren() to get the child nodes and loop over them.
applydatabase = FirebaseDatabase.getInstance().getReference().child("Apply").child(app).child("Applyid");
applydatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String first = null, second = null;
for (DataSnapshot child: dataSnapshot.getChildren()) {
if (first == null) {
first = child.getValue(String.class);
} else if (second == null)
second = child.getValue(String.class);
}
}
// TODO: compare first and second
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Related
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) {
}
});
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 :)
I am retrieving data from firebase database inside for loop , but problem is that firebase functions are not execute synchronously , i know firebase functions are asynchronous . is there any solution for that ?
Code :-
registrationReference.child(userId).child("generated_links").addListenerForSingleValueEvent(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
peopleModelList.clear();
for(DataSnapshot snapshot : dataSnapshot.getChildren())
{
peopleModel = new PeopleModel();
peopleHashMap =(HashMap)snapshot.getValue();
peopleModel.setChatWith((String)peopleHashMap.get("chatWith"));
peopleModel.setNickname((String)peopleHashMap.get("nickname"));
peopleModel.setChatRoom(snapshot.getKey());
Log.d("kkkk","1st");
if(peopleModel.getChatWith()!=null && !("".equals(peopleModel.getChatWith())))
{
registrationReference.child(peopleModel.getChatWith()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
peopleModel.setRefresh_token((String)dataSnapshot.child("refresh_token").getValue());
peopleModelList.add(peopleModel);
Log.d("kkkk","2nd");
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Log.d("kkkk","3rd");
}
iCallBackPeople.peopleAct(peopleModelList);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Output :-
1st
3rd
2nd
But i want output like this
1st
2nd
3rd
Note :-
i searched , but never got any solution !
How to get data from Firebase Database in a loop?
Firebase addListenerForSingleValueEvent excute later in loop
I tried this but not worked for me, it is fill my list with last item !
public void listOfUsers(final ICallBackPeople iCallBackPeople) {
count=0;
//peopleModelList = new ArrayList<>();
sortedMap = new TreeMap<>();
// peopleModelList = new ArrayList<PeopleModel>(sortedMap.values());
registrationReference.child(userId).child("generated_links").addListenerForSingleValueEvent(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// peopleModelList.clear();
for(DataSnapshot snapshot : dataSnapshot.getChildren())
{
peopleModel = new PeopleModel();
peopleHashMap =(HashMap)snapshot.getValue();
peopleModel.setChatWith((String)peopleHashMap.get("chatWith"));
peopleModel.setNickname((String)peopleHashMap.get("nickname"));
peopleModel.setChatRoom(snapshot.getKey());
//Object chatRoom = snapshot.getKey();
Log.d("kkkk","1st");
if(peopleModel.getChatWith()!=null && !("".equals(peopleModel.getChatWith())))
{
addItem(count,iCallBackPeople);
count++;
}
Log.d("kkkk","3rd");
}
Log.d("kkkk","end");
//iCallBackPeople.peopleAct(peopleModelList);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void addItem(final int index, final ICallBackPeople iCallBackPeople) {
registrationReference.child(peopleModel.getChatWith()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
peopleModel.setRefresh_token((String)dataSnapshot.child("refresh_token").getValue());
Log.d("kkkk","2nd");
sortedMap.put(index, peopleModel);
// sortedMap will sort your list by key (in this case, key is integer)
if(sortedMap.size()==2)
{
peopleModelList = new ArrayList<PeopleModel>(sortedMap.values());
iCallBackPeople.peopleAct(peopleModelList);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
I tried this but not getting all of the item only getting list with last item in snapshot
public void listOfUsers(final ICallBackPeople iCallBackPeople) {
peopleModelList = new ArrayList<>();
registrationReference.child(userId).child("generated_links").addListenerForSingleValueEvent(new ValueEventListener()
{
PeopleModel peopleModel;
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
peopleModelList.clear();
for(final DataSnapshot snapshot : dataSnapshot.getChildren())
{
peopleModel = new PeopleModel();
peopleHashMap =(HashMap)snapshot.getValue();
peopleModel.setChatWith((String)peopleHashMap.get("chatWith"));
peopleModel.setNickname((String)peopleHashMap.get("nickname"));
peopleModel.setChatRoom(snapshot.getKey());
if(peopleModel.getChatWith()!=null && !("".equals(peopleModel.getChatWith())))
{
getToken(new CallBackGetToken() {
#Override
public void token(String token) {
peopleModel.setRefresh_token(token);
Toast.makeText(context, token, Toast.LENGTH_SHORT).show();
peopleModelList.add(peopleModel);
//here i am checking my peopleModelList size is equal or not to snapshot
if(peopleModelList.size()==2)
iCallBackPeople.peopleAct(peopleModelList);
}
},peopleModel);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void getToken(final CallBackGetToken callBackGetToken ,PeopleModel peopleModel) {
registrationReference.child(peopleModel.getChatWith()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
callBackGetToken.token((String)dataSnapshot.child("refresh_token").getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
I think you should pass through an interface(create one and implement at this class). the method inside the interface should have a string as a parameter (it will receive your peopleModel.getChatWith() ) .
Inside your if(peopleModel.getChatWith()!=null && !("".equals(peopleModel.getChatWith())))you should request your interface.
I think is a solution for your asynchronously question.
Here is my solution:
int count =0;
SortedMap<Integer,PeopleModel> sortedMap;
private void set() {
count =0;
registrationReference.child(userId).child("generated_links").addListenerForSingleValueEvent(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
peopleModelList.clear();
sortedMap = new TreeMap<>();
for(DataSnapshot snapshot : dataSnapshot.getChildren())
{
peopleModel = new PeopleModel();
peopleHashMap =(HashMap)snapshot.getValue();
peopleModel.setChatWith((String)peopleHashMap.get("chatWith"));
peopleModel.setNickname((String)peopleHashMap.get("nickname"));
peopleModel.setChatRoom(snapshot.getKey());
Log.d("kkkk","1st");
if(peopleModel.getChatWith()!=null && !("".equals(peopleModel.getChatWith())))
{
addItem(count);
count++;
}
Log.d("kkkk","3rd");
}
iCallBackPeople.peopleAct(peopleModelList);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void addItem(final int index) {
registrationReference.child(peopleModel.getChatWith()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
peopleModel.setRefresh_token((String)dataSnapshot.child("refresh_token").getValue());
Log.d("kkkk","2nd");
sortedMap.put(index, peopleModel);
// sortedMap will sort your list by key (in this case, key is integer)
// you can get peopleModelList = new ArrayList<>(sortedMap.values);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Maybe I'm over simplifying it, but I feel like you should just use simple recursion.
List<People> peopleList;
int currentIndex = 0
private void myFirebaseMethodAction(person){
registerListener.onCallbacks(new ValueListener(){
onDataChanged(){
person.addStufforDoStuff();
if(peopleList.size > currentIndex + 1){
myFirebaseMethodAction(peopleList.get(++currentIndex)
}
}
onFailed(){
//handle it
}
}
}
Does that make sense?
Just saying walk the list with an index, simple.
btw above is pseduo code, don't copy verbatim lol.
I am trying to populate a TextView from a firebase database. Here is the sample json file.
{
"Player" : {
"Club" : "Valley Rovers",
"Name" : "John Murphy"
}
}
Here is my android code:
public class MainActivity extends AppCompatActivity {
private TextView mPlayer;
private DatabaseReference mDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPlayer = (TextView) findViewById(R.id.player);;
mDatabase = FirebaseDatabase.getInstance().getReference("Player").child("Name");
final String player = mDatabase.push().getKey();
mDatabase.child("Name").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Check for null
if (player == null) {
Log.e(TAG, "User data is null!");
return;
}
mPlayer.setText(player);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
I want to add the name John Murphy to the firebase database and doing so the TextView mPlayer will populate with John Murphy.
You are getting the child "Name" twice on your code (leading to Player/Name/Name). Remove it from the mDatabase initialization:
mDatabase = FirebaseDatabase.getInstance().getReference("Player");
And you're never really getting the value from the DataSnapshot received. To do so, use this:
mDatabase.child("Name").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String playerName = dataSnapshot.getValue(String.class);
mPlayer.setText(playerName);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
In case someone wants to use POJO approach to this problem in future, follow the example below:
Remove the child("Name") from mDatabase.child("Name").addValueEventListener(new ValueEventListener()
unless you want to fetch the "Name" child only. Also remember to effect the correction made on mDatabase initialization.
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// String playerName = dataSnapshot.getValue(String.class);
PlayerModel playerModel = dataSnapshot.getValue(PlayerModel.class);
((TextView)findViewById(R.id.textviewName)).setText(playerModel.getName());
((TextView)findViewById(R.id.textviewClub)).setText(playerModel.getClub());
// mPlayer.setText(playerName);
}
I want to load a dataset oncreate().
Since the data will not change, I use the one time loader:
protected void onCreate(Bundle savedInstanceState) {
....
mDatabase.child("users").child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
currentUser = dataSnapshot.getValue(Users.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "error:", databaseError.toException());
}
});
String name = currentUser.getName();
....
}
But the data is not available, the getName function is called on a null object.
How can I get the data onCreate()?
The problem is that Firebase uses an asynchronous listeners to a database reference, and you set name variable with null currentUser.
Try to declare the name var as final and before the listener, and set his value inside the firebase callback.
Update:
an example how to implement and use an "override" function:
final String name;
mDatabase.child("users").child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
currentUser = dataSnapshot.getValue(Users.class);
name = currentUser.getName();
fooFunc(name); // calling a function with data
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "error:", databaseError.toException());
}
});
#Override
public void fooFunc(String name) {
// name != null, when called from the the callback
// dont forget to check it
}