how to retrieve int from firebase - android

private void updateScoreBreaker(){
DBref=FirebaseDatabase.getInstance().getReference().child(Gamelevel);
Query maxScore =DBref.orderByChild(SCORE).limitToLast(1);
maxScore.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
maxScoreLevel=Integer.parseInt(dataSnapshot.child(SCORE).getValue(String.class));
maxScoreName=dataSnapshot.getKey();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
i have this error :
Cannot find local variable 'maxScoreLevel'

Seems like you haven't declared maxScoreLevel. You should declare it as a attribute of the class, so you can change it's value from the ValueEventListener.
class something {
...
Integer maxScoreLevel;
String maxScoreName;
...
private void updateScoreBreaker() {
DBref = FirebaseDatabase.getInstance().getReference().child(Gamelevel);
Query maxScore = DBref.orderByChild(SCORE).limitToLast(1);
maxScore.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
maxScoreLevel = dataSnapshot.child(SCORE).getValue(Integer.class);
maxScoreName = dataSnapshot.getKey();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
If corresponding reference does not exist or has no value, maxScoreLevel will be assigned with null value

Related

Firebase execute code IF child has been created

I have the following code for deleting some data form Firebase:
public void removeGameFromWaitQueue() {
final DatabaseReference data = FirebaseDatabase.getInstance().getReference().child("games").child(mCurrentGameKey);
data.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.exists()) {
mCurrentGame = snapshot.getValue(DatabaseModels.Game.class);
if (mCurrentGame.getState() == DatabaseModels.Game.State.OPEN.ordinal()){
data.removeValue();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
How can i check if "data" exists, then execute all the else code? Meaning that if i create the DatabaseReference, code works. But of course if i dont create the reference, then i have null exceprion. Should i have 2 listeners for this? And if yes, how is the best way to do it?
For future reference i solved it like this:
public void removeGameFromWaitQueue() {
final DatabaseReference data = FirebaseDatabase.getInstance().getReference().child("games").child(mCurrentGameKey);
data.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.exists()) {
mCurrentGame = snapshot.getValue(DatabaseModels.Game.class);
if (mCurrentGame.getState() == DatabaseModels.Game.State.OPEN.ordinal()){
data.removeValue();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
public void removeAfterCheck(){
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.hasChild("games")) {
removeGameFromWaitQueue();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Probably there is a better way, but this works for me in all cases as i want.

How to execute firebase function synchronously inside for loop?

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.

A new text should be displayed in textview every time the app launches

I have a textview in MainActivity.java. There are 5 strings (sentences) which are stored in firebase database. What I want is every time the MainActivity.java launches, a new string should be fetched from the database and must be displayed in the textview. But it only fetches the first string. I am not sure how to make this work! Is there any workaround? Any Help is appreciated.
MainActivity.java
public class Gridshow extends AppCompatActivity{
TextView myText;
private DatabaseReference database;
#Override
protected void onCreate(Bundle SavedInstanceState) {
super.onCreate(SavedInstanceState);
myText = (TextView) findViewById(R.id.Attri);
database = FirebaseDatabase.getInstance().getReference("StringList");
database.child("String1").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String sentName = dataSnapshot.getValue(String.class);
myText.setText(sentName);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Sample son file:
{
"StringList" : {
"String1" : "Valley Rovers",
"String2" : "John Murphy",
"String3" : "Hello all",
"String4" : "See you all",
"String5" : "Hey all"
}
}
The problem is that you're directly saying to FB to retrieve just the first string in here:
database.child("String1").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String sentName = dataSnapshot.getValue(String.class);
myText.setText(sentName);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You should retrieve the whole list and randomly choose the new string:
ArrayList<String> stringList = new ArrayList<>();
database.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, String> entries = (Map<String, String>) dataSnapshot.getValue();
stringList.addAll(entries.values());
selectString(stringList);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
public void selectString(ArrayList<String> list){
Random ran = new Random();
int x = ran.nextInt(list.size());
myText.setText(list.get(x));
}
use this
database = FirebaseDatabase.getInstance().getReference().child("StringList");
database.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String sentName = dataSnapshot.getValue(String.class);
myText.setText(sentName);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Well, in this line:
database.child("String1").addValueEventListener
You are fetching just String1. You should instead use something like this:
database.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(int i = 0;i<dataSnapshot.getChildren().size();i++){
if(i==positionOfStringYouWant){
String sentName = dataSnapshot.getValue(String.class);
myText.setText(sentName);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Android - Insert in DB if value is greater than the value in DB

I am using Android studio and Firebase to develop an application. I want to store a score in the database if the value is greater than the score in database. How do I check for that?
userData.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
userData.child("score").setValue(count);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You use the dataSnapshot to get the value from the reference.
Then, use that reference to update the data as you have, but add the conditional.
userData.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final String scoreKey = "score";
Long oldScore = dataSnapshot.child(scoreKey).getValue(Long.class);
if (oldScore == null || count > oldScore) {
userData.child(scoreKey).setValue(count);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Make sure that all Firebase single ValueEventsListeners finished

As mentioned in docs, it's better to fetch additional data, than nest objects in database.
According to this, how can I ensure that all data came?
I came up to this solution, but I'm not sure if this will work.
mPetsReference.addValueEventListener(new ValueEventListener() {
private List<Pair<Pet, Owner>> mData;
private long mChildrenCount;
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mData = new ArrayList<>();
mChildrenCount = dataSnapshot.getChildrenCount();
for (DataSnapshot data : dataSnapshot.getChildren()) {
Pet pet = data.getValue(Pet.class);
mOwnersReference.child(pet.getOwnerId())
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mData.add(new Pair<>(pet, dataSnapshot.getValue(Owner.class)));
if (mData.size() == mChildrenCount) {
everythingCame();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
mChildrenCount--;
if (mData.size() == mChildrenCount) {
everythingCame();
}
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Categories

Resources