FireStore Data insert (Android Studio 3.6.1) - java

I want to create new document in my DB in FireStore and insert a comment from my app, When I tried to debug My code in case of comment insert, I found
that onSuccess method is skipped, in every case when toAdd(String, this is the comment) isn't empty The
code runs onFailure Method, and I can't understand why. Here is my code:
public void insertComment(View v) {
toAdd = comment.getText().toString();
if (!toAdd.isEmpty()) {
//TODO : CHECK THIS SOLUTION (onSuccess not working)
String currentUser = FirebaseAuth.getInstance().getCurrentUser().getUid();
Map<String, Object> comment = new HashMap<>();
comment.put(COMMENT, toAdd);
db.collection("Users").document(currentUser+" Comments").set(comment)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
counter++;
ListItem listItem = new ListItem(counter, toAdd);
listItems.add(listItem);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
Toast.makeText(ListActivity.this, "Comment saved", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(ListActivity.this, "Error!", Toast.LENGTH_SHORT).show();
}
});
}
else {
Toast.makeText(ListActivity.this, "Empty Comment!", Toast.LENGTH_SHORT);
}
}

Solve it via Database -> Rules ->
Change allow read, write: if false; to true;

Related

How to get the firebase firestore document id

I am working on an application where i have list of items in recyclerview now on the recyclerview i have a heart icon when someone click on that icon that particular data added to the firebase and when again clikc on that data delete from the firebase now data is adding successully but i dont know why the data is not deleting from the firebase. please guide me
code is
holder.wishlist.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
int id = holder.getBindingAdapterPosition();
//CODE TO ADD THE ITEM TO THE WISHLIST
if(compoundButton.isChecked())
{
firebaseFirestore.collection("wishlistDetails").document(uid).set(wishMap).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
Toast.makeText(context, "added to firestire", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
Toast.makeText(context, "item added to wishlist" + id , Toast.LENGTH_SHORT).show();
}else {
//CODE TO REMOVE THE WISHLIST FROM FIREBASE
firebaseFirestore.collection("wishlistDetails").document(datalist.get(position).getID())
.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast.makeText(context, "removed", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
});
Try this -
In your wishlistmap add one more key id -- pass value uid for that key. Modify your wishlist model and add the id key.
Modify function for remove wishlist like below -
//CODE TO REMOVE THE WISHLIST FROM FIREBASE
firebaseFirestore.collection("wishlistDetails").document(list.get(position).getId())
.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast.makeText(context, "removed", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});

My app doesn't upload data to firestore, keeps in a loading loop

I have a setup system to send name, email, profile pic, biography and username.
Then I did check if the username is taken into Firebase Firestore by QuerySnapshot (working) my problem is that when I change to an available username, the app enters into a loading loop and do nothing more. It doesn't send to the database or anything else.
I tried many times to solve this problem, but didn't find any solution yet. I moved the code, reorganized and nothing seens to solve.
The method is inside the onClick from a button.
Here's the code:
submitBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setup_progressbar.setVisibility(View.VISIBLE);
String name = setup_name.getText().toString();
String username = setup_username.getText().toString();
String userbio = setup_bio.getText().toString();
String email = setup_email.getText().toString();
if (!TextUtils.isEmpty(name) && mainImageURI != null) {
Query mQuery = db.collection("Users")
.whereEqualTo("username", username);
mQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
for (DocumentSnapshot document: documentSnapshots){
if (document!=null){
duplicate = document.getString("username");
setup_username.setError("Ouch! This username is already taken. Please, try another.");
setup_progressbar.setVisibility(View.INVISIBLE);
} else {
if (isChanged) {
setup_progressbar.setVisibility(View.VISIBLE);
userid = firebaseAuth.getCurrentUser().getUid();
StorageReference imagePath = storageReference.child("profile_images").child(userid + ".jpg");
//StorageReference coverPath = storageReference.child("cover_images").child(userid + ".jpg");
imagePath.putFile(mainImageURI).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
imagePath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
storeFireStore(uri, name, username, userbio, email);
FancyToast.makeText(getApplicationContext(), getString(R.string.enviando_foto), FancyToast.LENGTH_LONG, FancyToast.CONFUSING, R.drawable.ic_upload, false).show();
setup_progressbar.setVisibility(View.INVISIBLE);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
String error = e.getMessage().toString();
FancyToast.makeText(getApplicationContext(), getString(R.string.fail_to_update_profile_pic) + error, FancyToast.LENGTH_LONG, FancyToast.ERROR, false).show();
setup_progressbar.setVisibility(View.INVISIBLE);
}
});
}
});
} else {
storeFireStore(null, name, username, userbio, email);
}
}
}
}
});
} else {
if (TextUtils.isEmpty(name)) {
setup_progressbar.setVisibility(View.INVISIBLE);
Snackbar snackbar = Snackbar.make(frameLayout, getString(R.string.empty_name), Snackbar.LENGTH_LONG);
snackbar.show();
} else if (TextUtils.isEmpty(username)) {
setup_progressbar.setVisibility(View.INVISIBLE);
Snackbar snackbar = Snackbar.make(frameLayout, getString(R.string.empty_username), Snackbar.LENGTH_LONG);
snackbar.show();
} else if (TextUtils.equals(username, duplicate)){
setup_username.setError("Ouch! This username is already taken. Please, try another.");
setup_progressbar.setVisibility(View.INVISIBLE);
} else if (TextUtils.isEmpty(email)) {
setup_progressbar.setVisibility(View.INVISIBLE);
Snackbar snackbar = Snackbar.make(frameLayout, getString(R.string.email_confirm), Snackbar.LENGTH_LONG);
snackbar.show();
} else {
setup_progressbar.setVisibility(View.INVISIBLE);
Snackbar snackbar = Snackbar.make(frameLayout, getString(R.string.pick_a_profile_pic), Snackbar.LENGTH_LONG);
snackbar.show();
}
}
}
private void storeFireStore(Uri uri, String name, String username, String userbio, String email) {
if (uri != null) {
downloadUrl = uri;
} else {
downloadUrl = mainImageURI;
//downloadUrl = mainCoverURI;
}
Map<String, String> userMap = new HashMap<>();
userMap.put("name", name);
userMap.put("username", username);
userMap.put("userbio", userbio);
userMap.put("email", email);
userMap.put("image", downloadUrl.toString());
//userMap.put("cover",downloadUrl.toString());
firebaseFirestore.collection("Users").document(userid).set(userMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
FancyToast.makeText(getApplicationContext(), getString(R.string.profileUpdated), FancyToast.LENGTH_LONG, FancyToast.SUCCESS, false).show();
setup_progressbar.setVisibility(View.INVISIBLE);
finish();
} else {
String error = task.getException().getMessage();
FancyToast.makeText(getApplicationContext(), getString(R.string.fail_to_update_profile) + error, FancyToast.LENGTH_LONG, FancyToast.ERROR, false).show();
}
}
});
}
});
Here's a screenshot of the screen loop.
You likely don't need (or want) a "snapshot listener" for this use case. You likely just want to do a one-time fetch to see if the given user name exists.
You likely want to use a TRANSACTION in Firestore to first read if a matching document exists and if not to transaction.set() a new document. That way if others come in at the same time trying to create a doc with the same username, only one of the competing concurrent transactions will succeed.
Consider inserting the document to Firestore before you upload the item to Storage. It is the document is Firestore that is the potential "race-condition". Once you "own" the FS document, you can take your time to upload/update other data.

Check if a value exist in more then on child Firebase Database in Android

I'm developing an android application for college project using Java and Firebase. I want to store the details of faculties working in college like name,email,department etc based on their position. I have created 3 child nodes HOD,Class mentor and lecturers inside Faculties as you can see that in here.
my problem is when I want to add the members inside any one these child I want to check if that members email ID is exist in any other childs. For example I want to add a member in HOD child.If this members email existed inside Lecturers child it should display Toast user already existed as Lecturer else it should add member inside Lecturer.
I used this code.
post = "HOD";
databaseReference.child(post).orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
Toast.makeText(MainActivityAddFaculty.this, "User already exist in "+post, Toast.LENGTH_SHORT).show();
} else {
post = "Class mentor";
databaseReference.child(post).orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
Toast.makeText(MainActivityAddFaculty.this, "User already exist in "+post, Toast.LENGTH_SHORT).show();
} else {
post = "Lecturer";
databaseReference.child(post).orderByChild("email").equalTo(email).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
Toast.makeText(MainActivityAddFaculty.this, "User already exist in "+post, Toast.LENGTH_SHORT).show();
} else {
checkData();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(MainActivityAddFaculty.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(MainActivityAddFaculty.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(MainActivityAddFaculty.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
It works fine but it's lengthy and also it takes time to check.If there is any better solution that would be very helpful.
This is is my code complete code for adding Faculties.
public class MainActivityAddFaculty extends AppCompatActivity {
private TextInputLayout addName, addEmail;
private TextInputEditText addEditName, addEditEmail;
private Button addBtn;
private Spinner addPositionSpinner,addDeptSpinner,addYearSpinner;
private TextView addPosition,addDept,addYear;
private String sDept = "Select department",sPost = "Select position",sYear = "Select year";
private String position,department,year,post;
private boolean b = false;
private FirebaseDatabase firebaseDatabase;
private FirebaseStorage firebaseStorage;
private DatabaseReference databaseReference,databaseReference2;
private StorageReference storageReference;
LoadingDialog loadingDialog;
private String facultyID;
private String name,email;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_faculty);
setTitle("Add Hod");
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
addName = findViewById(R.id.addFName);
addEmail = findViewById(R.id.addFEmail);
addEditName = findViewById(R.id.addFEditName);
addEditEmail = findViewById(R.id.addFEditEmail);
addBtn = findViewById(R.id.addFBtn);
addPositionSpinner = findViewById(R.id.addFPositionSpinner);
addPosition = findViewById(R.id.addFPosition);
addDeptSpinner = findViewById(R.id.addFDepartmentSpinner);
addDept = findViewById(R.id.addFDepartment);
addYearSpinner = findViewById(R.id.addFYearSpinner);
addYear = findViewById(R.id.addFYear);
addDeptSpinner.setVisibility(View.GONE);
addYearSpinner.setVisibility(View.GONE);
addDept.setVisibility(View.GONE);
addYear.setVisibility(View.GONE);
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference("FACULTIES");
facultyID = databaseReference.push().getKey();
loadingDialog = new LoadingDialog(MainActivityAddFaculty.this);
//selectPosition();
//TODO:Select position
List<String> categories = new ArrayList<>();
categories.add(0,"Select position");
categories.add("HOD");
categories.add("Class mentor");
categories.add("Lecturer");
ArrayAdapter<String> dataAdapter;
dataAdapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item,categories);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
addPositionSpinner.setAdapter(dataAdapter);
addPositionSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
addPosition.setText(parent.getSelectedItem().toString());
test();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
Toast.makeText(MainActivityAddFaculty.this, "Select a position", Toast.LENGTH_SHORT).show();
}
});
addBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
name = addEditName.getText().toString().trim();
email = addEditEmail.getText().toString().trim();
if (TextUtils.isEmpty(name)) {
Toast.makeText(MainActivityAddFaculty.this, "Enter name", Toast.LENGTH_SHORT).show();
}else {
if (TextUtils.isEmpty(email)) {
Toast.makeText(MainActivityAddFaculty.this, "Enter email.", Toast.LENGTH_SHORT).show();
} else {
checkData();
}
}
}
});
}
private void test(){
position = addPositionSpinner.getSelectedItem().toString();
if (position.equals(sPost)){
addDeptSpinner.setVisibility(View.GONE);
addYearSpinner.setVisibility(View.GONE);
addDept.setVisibility(View.GONE);
addYear.setVisibility(View.GONE);
}else if (position.equals("HOD")){
addDeptSpinner.setVisibility(View.VISIBLE);
addYearSpinner.setVisibility(View.GONE);
addDept.setVisibility(View.VISIBLE);
addYear.setVisibility(View.GONE);
} else if (position.equals("Class mentor")){
addDeptSpinner.setVisibility(View.VISIBLE);
addDept.setVisibility(View.VISIBLE);
addYearSpinner.setVisibility(View.VISIBLE);
addYear.setVisibility(View.VISIBLE);
} else if (position.equals("Lecturer")){
addDeptSpinner.setVisibility(View.GONE);
addYearSpinner.setVisibility(View.GONE);
addDept.setVisibility(View.GONE);
addYear.setVisibility(View.GONE);
} else {
addDeptSpinner.setVisibility(View.GONE);
addYearSpinner.setVisibility(View.GONE);
addDept.setVisibility(View.GONE);
addYear.setVisibility(View.GONE);
}
}
private void checkData(){
position = addPositionSpinner.getSelectedItem().toString();
department = addDeptSpinner.getSelectedItem().toString();
year = addYearSpinner.getSelectedItem().toString();
if (position.equals(sPost)){
Toast.makeText(this, "Select position", Toast.LENGTH_SHORT).show();
} else if (position.equals("HOD")){
if (department.equals(sDept)){
Toast.makeText(MainActivityAddFaculty.this, "Select department.", Toast.LENGTH_SHORT).show();
} else {
AddHOD addHOD = new AddHOD(name,position,department,email,facultyID);
databaseReference.child(position).child(facultyID).setValue(addHOD).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(MainActivityAddFaculty.this, "Faculty added successfully", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivityAddFaculty.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}else if (position.equals("Class mentor")){
//add Class mentor process started
if (!department.equals(sDept)){
if (!year.equals(sYear)) {
AddClassMentor addClassMentor = new AddClassMentor(name, position, department, year, email, facultyID);
databaseReference.child(position).child(facultyID).setValue(addClassMentor).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(MainActivityAddFaculty.this, "Faculty added successfully", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivityAddFaculty.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}else {
Toast.makeText(this, "Select year.", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Select department", Toast.LENGTH_SHORT).show();
}
} else if (position.equals("Lecturer")){
AddLecturer addLecturer = new AddLecturer(name,position,email,facultyID);
databaseReference.child(position).child(facultyID).setValue(addLecturer).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(MainActivityAddFaculty.this, "Faculty added successfully", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivityAddFaculty.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} else {
Toast.makeText(this, "Entry is pending.", Toast.LENGTH_SHORT).show();
}
}
}
Firebase's queries work on a list of nodes. Since you have a hierarchy, you'll need to fire the same query for each list you have in there, as you're doing today.
As usual when dealing with NoSQL databases, the solution is to model the data in a way that makes the use-case easiest. If you want to search across all members, store a single list of members:
"members": {
"$memberid": {
"email": "membersemail#institute.edu",
"memberType": "Class mentor" // or "HOD" or "Lecturer"
}
}
With the above structure you only have to execute one query to find all members with a specific email address.
You can either use the above structure to replace the three structures you currently have, or you can use it as an additional structure just for this use-case. Which one to choose depends on the other use-cases in your app, there is no solution that is right for all apps, just the one that works for you.
Enforcing uniques across values as you're doing here, will lead to scalability issues over time, as you:
Need to search across all members, which takes more time as you get more members.
More importantly: you will need to use a transaction to insert new users, to reduce the chances that multiple users claim the same email address at the same time.
This leads to a second scaling problem, as you'll need to run that transaction on the evert-growing /members node.
Finally: a malicious user can bypass the transaction by writing their own code, and still claim any email address.
Ensuring uniqueness on Firebase is only really enforceable if you use those values as the key in a list, so by maintaining a (additional) list of email addresses.
For more on this see:
Firebase security rules to check unique value of a child #AskFirebase
Firebase android : make username unique
How do you prevent duplicate user properties in Firebase?
Firebase realtime database validation username and email

android firestore: retrieve custom object from HashMap

I would like to store userdata in a document in Firestore. To do that I’m using a HashMap:
String userID = mAuth.getCurrentUser().getUid();
User user = new User(stringMail, stringUsername, stringGender, stringBirthday,
stringCountry, registeredOn);
HashMap<String, User> userHashMap = new HashMap<>();
userHashMap.put("userdata", user);
users.document(userID).set(userHashMap, SetOptions.merge())
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(RegisterActivity.this, "Upload completed to Firestore!", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(RegisterActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(RegisterActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
}
});
That works pretty good. I do have a problem though with retrieving the data. As the data is stored in a HashMap I can’t use following code:
String userID = mAuth.getUid();
users.document(userID).get()
.addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
Map<String, Object> userHashMap = new HashMap<String, Object>();
userHashMap = documentSnapshot.getData();
User user = (User) userHashMap.get("userdata");
I also can't use:
User user = documentSnapshot.toObject(User.class);
So I wondered whether someone can suggest a way how to retrieve a custom object from a HashMap? I should also mention that the document will contain a second HashMap.

Firebase Firestore get data from collection

I want to get data from my Firebase Firestore database. I have a collection called user and every user has collection of some objects of the same type (My Java custom object). I want to fill my ArrayList with these objects when my Activity is created.
private static ArrayList<Type> mArrayList = new ArrayList<>();;
In onCreate():
getListItems();
Log.d(TAG, "onCreate: LIST IN ONCREATE = " + mArrayList);
*// it logs empty list here
Method called to get items to list:
private void getListItems() {
mFirebaseFirestore.collection("some collection").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
if (documentSnapshots.isEmpty()) {
Log.d(TAG, "onSuccess: LIST EMPTY");
return;
} else {
for (DocumentSnapshot documentSnapshot : documentSnapshots) {
if (documentSnapshot.exists()) {
Log.d(TAG, "onSuccess: DOCUMENT" + documentSnapshot.getId() + " ; " + documentSnapshot.getData());
DocumentReference documentReference1 = FirebaseFirestore.getInstance().document("some path");
documentReference1.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
Type type= documentSnapshot.toObject(Type.class);
Log.d(TAG, "onSuccess: " + type.toString());
mArrayList.add(type);
Log.d(TAG, "onSuccess: " + mArrayList);
/* these logs here display correct data but when
I log it in onCreate() method it's empty*/
}
});
}
}
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show();
}
});
}
The get() operation returns a Task<> which means it is an asynchronous operation. Calling getListItems() only starts the operation, it does not wait for it to complete, that's why you have to add success and failure listeners.
Although there's not much you can do about the async nature of the operation, you can simplify your code as follows:
private void getListItems() {
mFirebaseFirestore.collection("some collection").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
if (documentSnapshots.isEmpty()) {
Log.d(TAG, "onSuccess: LIST EMPTY");
return;
} else {
// Convert the whole Query Snapshot to a list
// of objects directly! No need to fetch each
// document.
List<Type> types = documentSnapshots.toObjects(Type.class);
// Add all to your list
mArrayList.addAll(types);
Log.d(TAG, "onSuccess: " + mArrayList);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show();
}
});
}
Try this..Working fine.Below function will get Realtime Updates from firebse as well..
db = FirebaseFirestore.getInstance();
db.collection("dynamic_menu").addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if (e !=null)
{
}
for (DocumentChange documentChange : documentSnapshots.getDocumentChanges())
{
String isAttendance = documentChange.getDocument().getData().get("Attendance").toString();
String isCalender = documentChange.getDocument().getData().get("Calender").toString();
String isEnablelocation = documentChange.getDocument().getData().get("Enable Location").toString();
}
}
});
More reference
:https://firebase.google.com/docs/firestore/query-data/listen
If You do not want realtime updates refer Below Document
https://firebase.google.com/docs/firestore/query-data/get-data
Here is a simplified example:
Create a collection "DownloadInfo" in Firebase.
And add a few documents with these fields inside it:
file_name (string),
id (string),
size (number)
Create your class:
public class DownloadInfo {
public String file_name;
public String id;
public Integer size;
}
Code to get list of objects:
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("DownloadInfo")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
if (task.getResult() != null) {
List<DownloadInfo> downloadInfoList = task.getResult().toObjects(DownloadInfo.class);
for (DownloadInfo downloadInfo : downloadInfoList) {
doSomething(downloadInfo.file_name, downloadInfo.id, downloadInfo.size);
}
}
}
} else {
Log.w(TAG, "Error getting documents.", task.getException());
}
}
});
db.collection("users").get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data()}`);
});
source:-
https://firebase.google.com/docs/firestore/quickstart
This is the code to get the list.
Since this is an async task, it takes time that's why the list size shows empty at first.
But including the source for the cache data will enable the previous list(and also its size) to be in memory until next task is performed.
Source source = Source.CACHE;
firebaseFirestore
.collection("collectionname")
.get(source)
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
if (documentSnapshots.isEmpty()) {
return;
} else {
// Convert the whole Query Snapshot to a list
// of objects directly! No need to fetch each
// document.
List<ModelClass> types = documentSnapshots.toObjects(ModelClass.class);
// Add all to your list
mArrayList.addAll(types);
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});

Categories