Any idea why this doesn't work?
mFirestore.collection("DR1")
.document(UserID)
.collection("Story")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot document : task.getResult()) {
spinnerArray.add(String.valueOf(document.getId()));
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
The spinner drop down works (with no default selection, just empty), but on selection, it also does not appear. No error whatsoever. I have setOnItemSelectedListener to Toast.maketext on a selection, but nothing appears as well.
But once I add a:
spinnerArray.add("test");
Before the Firestore database call (the for-loop), then everything works fine. (default selection on "test" on the dropdown list, and when I select another entry, Toast.maketext appears, and selection appears on the spinner)
Thanks again.
This is happening because you are not defining your spinnerArray inside the onComplete() method, which has an asynchronous behaviour. To solve this, move the declaration of your spinnerArray inside the onComplete() method. To display your records you also need to set the adapter inside the method. For more information please see my answer from this post. I also recommend that you see this video, Asynchronous Firebase API - Cloud Firestore and Android, for a better understanding.
Related
I'm trying to get any user that has "like" or "dislike" as string value besides myself, but my code is simply jumping of to the end of the function without executing the code inside. What do I have to change? I tried in another project to test and it worked fine, I just did a copy and paste with the function and now it isn't working.
Sorry for my poor english, I'm brazillian.
private void getMyIdEqualLike() {
Query query = usersReferenceDb.document(userCardViewID).collection("connections").whereEqualTo(myUId, "like");
query.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
uConnectID = queryDocumentSnapshots.getDocuments().toString();
}
});
}
The getDocuments() function it's supposed to return a list with a documentSnapshot of my user if it's equal to "like" and if it isn't then returns "[]" as empty list, but I'm getting null from uConnectID variable, so I debugged it step by step and I saw that it stops at "query.get().addOnSuccessListener..." and jump right to the end of it's function.
Use addOnCompleteListener and check if the query.get() is completing successfully or not.
Your code has onSuccessListener which will only be triggered if the call was successful.
I have trouble adding data in ArrayList.
I tried to add data in array list but got nothing
Here's my code
public class fmMain extends Fragment {
private ArrayList<markerList> posList = new ArrayList<markerList>();
public fmMain() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
//Firebase get data
stores.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for (QueryDocumentSnapshot documentSnapshot: queryDocumentSnapshots){
markerList m = new markerList(documentSnapshot.getId());
posList.add(m);
}
Log.d(TAG,posList.toString()); //got value
}
});
Log.d(TAG,posList.toString()); //got nothing
}
as you can see when I tried to add value in function onSuccess I got value that has been added but when I tried to add outside function I got nothing
And here is my database structure
You cannot simply use the posList list outside the onSuccess() method because it will always be empty due the asynchronous behaviour of this method. This means that by the time you are trying to print posList.toString() outside that method, the data hasn't finished loading yet from the database and that's why is not accessible. A quick solve for this problem would be to use the list only inside the onSuccess() method, as in the following lines of code:
stores.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
List<GeoPoint> list = new ArrayList<>();
for (QueryDocumentSnapshot document : task.getResult()) {
list.add(document.getGeoPoint("position"));
}
//Do what you need to do with your list
}
}
});
If you want to use that list outside this method, I recommend you see my anwser from this post where I have explained how you can solve this using a custom callback. You can also take a look at this video for a better understanding.
You are getting this error because you are mixing asynchronous calls with synchronous ones. The onSuccess method (Asynchronous) will be called when you receive the data successfully from Firebase. But the onCreateView method will not wait for that. It will directly go to the second
Log.d(TAG,posList.toString()); //got nothing
and you will get nothing (actually I think you'll get an empty string) because you haven't received the data yet.
I'm using Google Play Services for my libgdx game. I created some dummy achievements to test and later wanted to remove them. On my phone I went to Google Play Games -> Settings -> Delete Play Games Data -> Deleted data from my game.
After going back into my game, I noticed that the game thought I was still signed in. I use the following code to check if a user is signed in:
#Override
public boolean isSignedIn(){
return GoogleSignIn.getLastSignedInAccount(androidLauncher) != null;
}
If the user is not signed in, I try to sign them in silently
private void signInSilently() {
signedInClient.silentSignIn().addOnCompleteListener(androidLauncher,
new OnCompleteListener<GoogleSignInAccount>() {
#Override
public void onComplete(#NonNull Task<GoogleSignInAccount> task) {
if (task.isSuccessful()) {
signedInAccount = task.getResult();
}
}
});
}
If I can't sign them in silenty. I create a new intent and have them manually sign in and give access to the app:
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
signedInAccount = result.getSignInAccount();
showSignedInDialog();
}
The problem is, after deleting the Play Games Data, my method isSignedIn is always returning true. However, when I try to do something like display achievements, I get the following error:
com.google.android.gms.common.api.ApiException: 4: The user must be signed in to make this API call.
Code for showing achievements:
#Override
public void showAchievements(){
androidLauncher.runOnUiThread(new Runnable() {
#Override
public void run() {
if (isSignedIn()) {
loadingView.showLoadingView();
Games.getAchievementsClient(androidLauncher, signedInAccount)
.getAchievementsIntent()
.addOnSuccessListener(new OnSuccessListener<Intent>() {
#Override
public void onSuccess(Intent intent) {
androidLauncher
.startActivityForResult(intent, RC_ACHIEVEMENT_UI);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Logger.error(e);
}
})
}
}
});
}
I'm curious as to why this is happening. According to the documentation, my isSignedIn method should be working correctly. However, because I'm getting the error that I'm getting when I actually try to make an API call, it appears that the method is not working. I can only assume that all of this is stemming from me deleting my Play Games Data as everything worked fine up until that point.
Something else I want to note - I tried having my isSignedIn method return false to force a silent sign in. My silent sign in returned the following error:
com.google.android.gms.common.api.ApiException: 8: 8:
I did a bit of research and found a bug report. It looks like a status code of 8 is an Internal Error. Google at least seems to be aware of the issue.
Update: After having my isSignedIn method return false, and after disabling my silent sign in, I forced a manual sign in. After forcing the manual sign in, and signing in, it now works. However, I won't be able to do that for users if they run into the same issue. They would be stuck as the isSignedIn method seems to always return true after deleting the Play Games Data.
I had a similar issue and what worked for me was enabling the Google Drive API for my project. Not sure why this worked, but it did.
Go to https://console.developers.google.com/apis, then open the "Library" menu option. From there, search for "Drive" and click on the "Google Drive API" item. You should then see an enable button.
I managed to get data from the Firebase Database and show it in an alphabetical order in my ListView.
Now I want to show the value from my database, if I click on an item in the ListView. As an example in my database it says "BB" as a name and the value is "Bye, bye".
So after an onClick event in the ListView a Toast message should show the value. How can I do this?
HereĀ“s my database:
To show the value after you click on an item:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference();
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
final String selectedFromList = (String) list.getItemAtPosition(position);
ref.orderByChild(selectedFromList).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String retrievedValue=dataSnapshot.child(selectedFromList).getValue().toString();
Toast.makeText(activity_name.this, "Value: "+retrievedValue, Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Assuming you have a listview with the following:
Afk
MFG
After clicking on an item, get the item at that postion and use it in a query orderByChild and retrieve it's value.
The sample code 'Peter Haddad' provided in his answer basically works fine... IF you design your database in a better way I did back then.
If you use his code, you get the value of the database entry (so the text on the right side in the console database, but I wanted to get the left one.
I recommend using a structure like in the Firebase Docs about Structuring.
It could look something like this:
Here are two posts about searching and querying those kind of databases:
How to do a simple search in string in Firebase database?
Query based on multiple where clauses in Firebase
If you anyways want to do it in the way I tried, it`s possible:
In the sample code from 'Peter Haddad' simply replace dataSnapshot.child(selectedFromList).getValue().toString() with dataSnapshot.child(selectedFromList).getKey().toString().
The key represents the text on the left side of the console database structure.
I have a app in building proccess in some where i need to get data from FirebaseDatabase and show them in custom list view here my code part of it for onDataChange method
myDatabase=FirebaseDatabase.getInstance();
myRef= myDatabase.getReference().child("TvSeries");
myAuth = FirebaseAuth.getInstance();
myUser = myAuth.getCurrentUser();
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot currentData : dataSnapshot.getChildren()){
if(currentData.child("tCategory").child("tPrimary").getValue().toString().equals("Aksiyon")){ }
selectedCategoryList.add(new DataForRow(currentData.getKey(),
currentData.child("tCategory").child("tPrimary").getValue().toString(),
currentData.child("tReleaseDate").getValue().toString()));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Integer size =selectedCategoryList.size();
Log.d("Size:", size.toString());
When i put in breakpoint onDataChange method it works but otherwise it didnt any suggestion is very helpful. Have a nice day all.
Your selectedCategoryList list is always empty because onDataChange() method has an asynchronous behaviour which means that is called even before you are try to add those objects of DataForRow class to the list. A quick solve for this problem would be to declare and use your selectedCategoryList list only inside the onDataChange() method or if you want to use it outside, you need to create your own callback and for that, I recommend you see the last part of my answer from this post.
Firebase works asynchronously. You probably got the data from firebase after you program executed the line with Log. As Tristan mentioned, if you put your Log inside of the listener, it will work