CollectionGroup query in firestore android studio - java

I am not able enter into for loop. it is not showing any error. when I try to debug it is not entering for loop. after entering into for loop only it can retrieve result. can any one help?
Query query =fstore.collectionGroup("ride").whereEqualTo("from",from1).whereEqualTo("to",to1).whereEqualTo("date",date);
query.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot snapshots) {
for (QueryDocumentSnapshot queryDocumentSnapshot:snapshots)
{
String source = queryDocumentSnapshot.getString("from");
String destination = ueryDocumentSnapshot.getString("to");
String date1 = queryDocumentSnapshot.getString("date");
String time = queryDocumentSnapshot.getString("time");
String vehicle = queryDocumentSnapshot.getString("vehicle number");
String cost = queryDocumentSnapshot.getString("Cost per person");
String seats = queryDocumentSnapshot.getString("number of seats");
String model = queryDocumentSnapshot.getString("car model");
data += source+" "+destination+" "+date1+" "+time+" "+vehicle+" "+cost+" "+seats+" "+model+"\n";
}
});
enter image description here

In the reference you may find following sentence:
Before using a collection group query, you must create an index that supports your collection group query. You can create an index through an error message, the console, or the Firebase CLI.
From the same reference example it seems that code is done properly. Of course we do not know what do you have in from1, to1 and date variables. From the screenshot it seems that date has strange format in your database. As well I am not sure how it will work with multiple whereEqualTo methods.
So many think could go wrong here, but if I were in your shoes I would start with checking the indexes, and than start from building query with single whereEqualTo trying to get anything from database, exactly like in the reference example.
If you succeed than you can extend it to more sophisticated solutions.
I hope it will help!

Related

I want to check if my users input contains a substring that is a document in my firestore database, is this possible in Java? (Android-studio)

In the following code, 'question' is a string variable created by a users voice input. this question is compared with document IDs in my firebase cloud firestore.
public void setAnswer(String question){
FirebaseFirestore JLdatabase = FirebaseFirestore.getInstance();
DocumentReference docRef = JLdatabase.collection("Products").document(question);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
textViewAnswer.setText(document.getString("location"));
} else {
textViewAnswer.setText("I can't help you with this yet");
}
} else {
textViewAnswer.setText("Oeps. Something went wrong");
}
}
});
If question is exactly equal to the document ID, it works, but most of the time something slightly different will be said.
Now I want to check if there is a word/word combination in the question that's equal to one of my documents ID. Is this possible in Java? I couldn't find something like this on the web.
If there is a better way to solve a problem like this. I would like to here!
If a question is exactly equal to the document ID, it works
It works because you are pointing to the document that has that exact id.
Now I want to check if there is a word/word combination in the question that's equal to one of my documents ID.
Unfortunately, there is no way you can create a query to search for a substring in the document id. The only option that you have is to create a property of type String that can hold the question and perform a query using one of my solutions that can be found in my answer from the following post:
Search by pattern on Cloud Firestore collection
what I would do is :
Create a field name that stores question that follows your document ID
Store the question as an array. (meaning each word is its own array)
Perform a firebase query with the function array-contains
Remember how I told you to store your question as an array (e.g ["How", "are", "you])? Well because firebase do not have the LIKE operation as to SQL
After performing your query, you can get the document ID and pass it into the document reference

Order a ParseQuery by the date at which only one field has been updated

I have a feed containing posts that are currently ordered by "updatedAt". My original intention was to push up posts to the top of the feed which were last replied to (I do this by incrementing a "replyCount" field in each post when a user leaves a comment), not totally cognizant of the fact that another field, "likeCount" is also being updated when user's "like" a post. I would still like to push those posts that were recently "replied to" to the top of the feed, but do not at the expense of the weird UX behavior that associated with liking posts pushing them up as well. I'm not sure how to separate the two.
What should I do here? Can I maybe add another column called "lastReplyCountTime" and then sort queries based on that? Maybe set lastReplyCountTime for all posts to the current time when saved to the database, and then only update that value when a post receives a reply?
String groupId = ParseUser.getCurrentUser().getString("groupId");
ParseQuery<ParseObject> query = new ParseQuery<>(ParseConstants.CLASS_POST);
query.whereContains(ParseConstants.KEY_GROUP_ID, groupId);
/*query.addDescendingOrder(ParseConstants.KEY_CREATED_AT);*/
query.orderByDescending("updatedAt");
query.findInBackground((posts, e) -> {
if (mSwipeRefreshLayout.isRefreshing()) {
mSwipeRefreshLayout.setRefreshing(false);
}
if (e == null) {
// We found messages!
mPosts = posts;
String[] usernames;
usernames = new String[mPosts.size()];
int i = 0;
for(ParseObject post : mPosts) {
usernames[i] = yeet.getString(ParseConstants.KEY_SENDER_NAME);
i++;
}
FeedAdapter adapter = new FeedAdapter(
getListView().getContext(),
mYeets);
setListAdapter(adapter);
}
});
}
You have 2 options:
Like you suggested you can create another date property let's call it sortedUpdatedAt and update it with the current date each time you are updating the relevant values
If you still want to use updatedAt you can wrap your like object in a separate parse object (class). This class will be saved as a relation in the parent class and then each time the user "like" you can just update only this class and not the whole object. This way the updatedAt of your parent object will not be changed.
I think that option 1 is great since it's not so complicated and you can do it very quick.

Multiple entries in a JTable from a Database

This is my first question here and I hope I am not repeating someone else's question. I will try and explain the problem as much as I can in the next few lines. Pardon my English if its really bad .
So I have here a JTable in which I would like to retrieve values from a database. So far I can add 1 value and I know why this is. The question is . How do I add multiple values to this table ?
This is the method I use in my operations to find a gun in a specific shop with its quantity
public ResultSet gunSearch(String id, int qty, int storeId) {
try {
String s = "SELECT gunID, gunName AS \"Gun Name\", gunPrice AS \"Price\", SellCost AS \"Cost\", availableQty AS \"Amount Available\", "+qty+" AS \"Quantity\" FROM Guns WHERE gunId = '" + id + "'AND storeId='"+storeId+"'";
pstmt = conn.prepareStatement(s);
rset = pstmt.executeQuery(s);
} catch (Exception ex) {
System.out.println("Error here at searchByProdId Operation "+ex);
}
return rset;
}
For my GUI I use the following code to display the information entered by the user
public void actionPerformed(ActionEvent e){
if(e.getSource().equals(enterBtn)){
String gunID = gunIdText.getText();
int qty = Integer.parseInt(quantityText.getText());
table.setModel(DbUtils.resultSetToTableModel(op.gunSearch(gunID, qty, storeId)));
Whenever I click the Enter button the column of data is retrieved from the database. However if I re-enter another gunId and quantity , the previous column disappears and the new column of data is retrieved from the database.
How could I possibly , enter couple of different gunId's and quantitie's into the JTable ?
Your gunSearch method only returns one result. You then completely recreate the TableModel from this one result, erasing whatever you had in the old model.
You'll need to concoct a new method that can take a Collection<String> (a collection of gun ids) and return a row for each id provided.
Alternatively, you can create a method that adds a gun to an existing TableModel rather than recreating the whole model from scratch every time. It depends on how you want the application to work, which option is better.

Hibernate caches the query while data is being changed

I'm developing an application which connects to an outside service to fetch new SMS. Theses messages are stored in a local database by Hibernate. My client can search these messages based on numerous parameters such as time, number, and etc.
After calling the search method with a list of parameters called 'List1', I get the desired result without any problems. Though while I'm waiting for this result a new message has arrived.
Soon after, I call the search method with same parameter list again and I'm expecting to get the new message as well, but I get the previous result.
I have checked my database and the new message is present so all I can think of is Hibernate caching. Since both queries are exactly the same, I guess hibernate return the same result set as before.
In case my assumption is correct, how can I overcome this problem? If not, so what exactly is going on?
Edit
here is relevant part of my source code. Following two methods will be invoked when client initiates a search request:
smsService.refresh();
JSONArray result = smsService.retrieveMessages(...);
#Transactional
public JSONArray retrieveMessages(Long periodBegining, Long periodEnd, String order, Integer limit, String profile, Boolean unread, String correspondent) {
List<ShortMessage> messageList = shortMessageDAO.find(beginDate, endDate, order, limit, profile, unread, correspondent);
JSONArray result = new JSONArray();
for (ShortMessage message : messageList)
result.put(message.toJSON());
shortMessageDAO.markRead(messageList);
return result;
}
#Transactional
public void refresh() {
webService.authentication(serviceUsername, servicePassword);
while(webService.hasUnread() > 0) {
SMS sms = webService.retrieveMessage();
ShortMessage message = new ShortMessage(sms.getHash(), sms.getFrom(), sms.getTo(), "DEFAULT", sms.getMessage(), new Date(sms.getTime()), true);
shortMessageDAO.insert(message);
}
}
}
public List<ShortMessage> find(Date beginDate, Date endDate, String order, Integer limit, String profile, Boolean unread, String correspondent) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ShortMessage.class);
criteria.add(Restrictions.ge("time", beginDate));
criteria.add(Restrictions.le("time", endDate));
criteria.add(Restrictions.eq("profile", profile));
if (unread)
criteria.add(Restrictions.eq("unread", true));
if (correspondent != null)
criteria.add(Restrictions.eq("origin", correspondent));
criteria.addOrder(order.equals("ASC") ? Order.asc("time") : Order.desc("time"));
criteria.setMaxResults(limit);
criteria.setCacheMode(CacheMode.IGNORE);
return (ArrayList<ShortMessage>) criteria.list();
}
Yes it looks like hibernate is caching your query and returning cached results.
Please give us a overview of your code to suggest better.
Below listed are two ways of controlling the caching behaviour of queries:-
1) At the main named query level:-
#NamedQuery(
name = "myNamedQuery"
query = "SELECT u FROM USER WHERE u.items is EMPTY"
hints = {#QueryHint(name = "org.hibernate.cacheMode", value = "IGNORE")}
)
2) At individual query level :-
Query q = session.createQuery("from User")
.setCacheMode(CacheMode.IGNORE);
After running numerous test, I found out that this problem is not cache related at all. Upon receiving each message I would have stored the time of arrival based on data provided by SMS panel and not my own machine time.
There was a slight time difference (20 seconds to be exact) between those 2 which was the reason behind the query not returning the new received message.

How to use a get method for a SQLite Database management class in another class?

What I am trying to do is retrieve an ArrayList from another database manager class. Unfortunately all I can do because the manager class cannot work statically is create an instance in another class, then call the method. Then I got myself into passing that same instance into the method which asked for an SQLiteDatabase object. Now I've worked myself into a bind of confusion, when all I really want is to do is retrieve the arraylist to display a listview of elements from an SQL column.
EDIT: My post lacked clarity, so I'll try to specify exactly what is going wrong and what I am trying to accomplish here:
In a display (output) activity, I am trying to use a ListView to display elements contained in an SQL database. Currently, I am only focusing on one column (Assignment Names). My approach involved using a get method built into the database manager class, but because you cannot reference that method statically, I tried to use the method by creating an instance of that manager class. This would return an ArrayList of Inputted objects (each containing a name). It seemed to have worked, but when running the program, the LogCat protested that I was calling getDatabase recursively. After looking online, people recommended that I fix the issue by changing the method to ask for (SQLiteDatabase db) as parameters so the same database gets tossed around in the manager. Now I get confused here-- I'm not sure what to pass into this method from the display activity. It also doesn't help that from what I've heard from the comments, my get method doesn't traverse the SQL database properly. If you can solve this puzzle THANK YOU!
I'll post my code for diagnosis, hopefully an outside view will show exactly what's wrong with everything I'm trying here.
public Cursor getAssignmentNames(SQLiteDatabase db) {
return db.query(false, ASSIGNMENT_TABLE, COLUMN_TITLES,
" WHERE " + ASSIGNMENT_NAME + " ", null, null, null, " ORDER BY "+ASSIGNMENT_URGENCY_RATING, null);
}
/
public ArrayList<Inputted> getListOfAssignments (SQLiteDatabase db) {
Cursor names = getAssignmentNames(db);
ArrayList<Inputted> assList = new ArrayList<Inputted>();
names.moveToFirst();
while (!cursorsAreAfterLast(names) ) {
int go = 0;
assList.add(new Inputted(names.getString(go))
names.moveToNext();
go++;
}
return assList;
}
/
DBRecordsLayer assignmentRecords = new DBRecordsLayer(this,
"assignment.db", null, 1);
ArrayList<Inputted> assList = DBRecordsLayer.getListOfAssignments(assignmentRecords);
Your code is a bit confusing... In each iteration of the while loop, you are incrementing the cursor (names.moveToNext()); You are also incrementing go.
The result would be:
1st iteration: You are taking the data from the first column of the first query
2nd iteration: You are taking the data from the second column of the second query
etc...
I'm assume that you want to be reading data from the same column of the database for each iteration.
try this:
public ArrayList<Inputted> getListOfAssignments (SQLiteDatabase db) {
Cursor names = getAssignmentNames(db);
ArrayList<Inputted> assList = new ArrayList<Inputted>();
names.moveToFirst();
columnContainingStringToSendToInputtedConstructor = x; //replace the x with column you need from your table
while (!names.isAfterLast()) {
assList.add(new Inputted(names.getString(columnContainingStringToSendToInputtedConstructor));
names.moveToNext();
}
}

Categories