Im trying to check if a (string)serial number writen in an EditTextView is equal to any of the string fields called serial number of my documents in the collection, but every time I try i get an error or a crash or it goes to the previous activity and i dont really know what to do, i have tried to look at the documentation which was very helpful with writing data to the database but not at getting it as in the example shown doc:
db.collection("cities")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
I dont really understand like how would you assign any of the data gathered after this.
this is my data structure in the collection:
there are 8 lockers, each serial number is just the 6 times the locker number, same with cells there are 8 of them in each locker
Lockers (collection)
--locker1 (document)
----full (bool field)
----serial number (string field)
----Cells (sub collection)
------cell1 (document in sub collection)
--------active (bool field)
--------cell number (number field)
--------user (string field)
I have created beforehand Locker and Cell class:
public class Locker {
private String serialNumber;
private ArrayList<Cell> cells;
private boolean full;
public Locker(String serialNumber, ArrayList<Cell> cells, boolean full) {
this.serialNumber = serialNumber;
this.cells = cells;
this.full = full;
}
public Locker(String serialNumber, ArrayList<Cell> cells) {
this.serialNumber = serialNumber;
this.cells = cells;
this.full = false;
}
public Locker(String serialNumber){
this.serialNumber = serialNumber;
this.cells = new ArrayList<Cell>(8);
for(int i = 1; i <= 8; i++){
cells.add(new Cell(false, i));
}
this.full = false;
}
}
public class Cell {
private boolean active;
private int cellNumber;
private User user;
public Cell(boolean active, int cellNumber, User user) {
this.active = active;
this.cellNumber = cellNumber;
this.user = user;
}
public Cell(boolean active, int cellNumber){
this.active = active;
this.cellNumber = cellNumber;
this.user = null;
}
}
after i have explained all that to google bard i asked it to write me a code that will do that and it came up with this:
public ArrayList<Locker> getLockersFromFirestore(FirebaseFirestore db) {
final ArrayList<Locker> lockerList = new ArrayList<>();
CollectionReference lockersRef = db.collection("Lockers");
lockersRef.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot lockerDoc : task.getResult()) {
Locker locker = processLockerDocument(lockerDoc);
lockerList.add(locker);
}
// Use the lockerList for further processing
} else {
Log.w("Firestore", "Error getting lockers.", task.getException());
}
}
});
// This method returns an empty list until the asynchronous task completes (I dont really understand what it means ;-; does it mean it doesnt return an arraylist of Locker? )
// Consider using a callback or LiveData to handle the asynchronous nature (please someone clear this out for me)
// in your activity or fragment.
return lockerList;
}
private Locker processLockerDocument(QueryDocumentSnapshot lockerDoc) {
String serialNumber = lockerDoc.getString("serialNumber");
boolean full = lockerDoc.getBoolean("full");
// Get Cells subcollection reference
CollectionReference cellsRef = lockerDoc.getReference().collection("Cells");
// This ArrayList will be used to temporarily store Cell objects
final ArrayList<Cell> cellList = new ArrayList<>();
cellsRef.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot cellDoc : task.getResult()) {
Cell cell = processCellDocument(cellDoc);
cellList.add(cell);
}
} else {
Log.w("Firestore", "Error getting cells for locker " + serialNumber, task.getException());
}
}
});
// Wait for Cells subcollection retrieval to complete before creating Locker object
// This approach might block the main thread for a short time. Consider using a callback
// or LiveData for asynchronous handling. (what does it mean ;-; )
while (cellList.isEmpty()) {
try {
Thread.sleep(100); // Sleep for a short duration to avoid busy waiting
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return new Locker(serialNumber, cellList, full);
}
private Cell processCellDocument(QueryDocumentSnapshot cellDoc) {
boolean active = cellDoc.getBoolean("active");
int cellNumber = cellDoc.getLong("cellNumber").intValue(); // Assuming cellNumber is stored as a Long
//User user = null; // Handle user data retrieval if needed (assuming User class exists)
return new Cell(active, cellNumber);
}
after that by what i undestand i just have to put getLockersFromFirestore
where i check the serial numbers, so thats what i did:
@Override
public void onClick(View view) {
if(view == btCheck){
//user enters serial number in etView, clicks the check button
//all serial numbers are being saved in serialNums and later checked if any equals the one writen
//in etView
boolean found = false;
String[] serialNums = new String[8];
for(int i = 0; i < 8; i++){
serialNums[i] = getLockersFromFirestore(db).get(i).getSerialNumber();
}
for(int i = 0; i < serialNums.length; i++){
if(etView.getText().toString().equals(serialNums[i])){...}}
Im sorry it came out so lomg and I my self am confused, im new to android and firestore, maybe its something to do with the async stuff but im very unfamiliar with the whole concept especially in android, big thanks to everyone
Alon Belkin is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.