How to get unread messages using FQL? - android
I am trying to get the body and the sender of all unread inbox .
To get all conversation's threads with unread messages I used this query:
SELECT thread_id from unified_thread WHERE folder='inbox' AND unread=1
to get the unread message of a thread I used this query
SELECT sender,body FROM unified_message WHERE unread=1
I have tried the following nested query :
SELECT sender,body FROM unified_message WHERE thread_id IN (SELECT thread_id FROM unified_thread WHERE folder = 'inbox' AND unread=1) AND unread=1"
but I only get unread message from one thread and not all unread threads.
I also tried multiquery like this:
String query1="SELECT thread_id FROM unified_thread WHERE folder='inbox' AND unread=1";
String query2="SELECT timestamp,sender,body FROM unified_message WHERE unread=1 AND thread_id IN (SELECT thread_id FROM #query1)";
Bundle params = new Bundle();
JSONObject jsonFQL=new JSONObject();
try {
jsonFQL.put("query1",query1);
jsonFQL.put("query2",query2);
} catch (JSONException e) {
e.printStackTrace();
}
params.putString("method","fql.multiquery");
params.putString("queries", jsonFQL.toString());
new Request(session,"/fql",params,HttpMethod.GET,new Request.Callback(){
public void onCompleted(Response response) {
...
}
).executeAsync(); ....
but I got error:
errorMessage: Unsupported method, fql.multiquery
Then I tried with INNER JOIN:
SELECT unified_message.sender,unified_message.body
FROM unified_message
INNER JOIN unified_thread
ON unified_message.thread_id=unified_thread.thread_id
WHERE unified_thread.unread=1
but I got this error:
Parser error: unexpected 'INNER' at position...
I learnt JOIN is not supported in FQL
Can somebody give me a hand to do this query in FQL ??
example of needed output: I have 5 conversations with different people, but only 3 conversations have unread messages. So I would like to get
something like this:
UNREAD MESSAGES
Sender: Anna
Body: hello dude
Body: how are you?
Body: I miss you
Sender: John
Body: please help me
Sender: Erick
Body: nice
Body: buddy
This works:
SELECT sender, body FROM unified_message
WHERE thread_id IN
(SELECT thread_id FROM unified_thread WHERE folder = 'inbox' AND unread=1)
AND unread=1
ORDER BY timestamp DESC
It is important to sort the messages you retrieve in a descending order using:
ORDER BY timestamp DESC
Otherwise, only the first older messages of the conversation will be examined, whereas unread messages should be recent.
Just for your knowledge, here is the corresponding multi-query, which gives the same result:
{
"threads":"SELECT thread_id FROM unified_thread WHERE folder='inbox' AND unread=1",
"messages":"SELECT sender, body FROM unified_message WHERE thread_id IN (SELECT thread_id FROM #threads) AND unread=1 ORDER BY timestamp DESC"
}
However, you should not use FQL anymore:
Version 2.0 of the Facebook Platform API is the last version where FQL
will be available. Versions after 2.0 will not support FQL. Please
migrate your applications to use Graph API instead of FQL. Please see
our changelog for current version information.
I suggest you use the following Graph API tables:
thread
message
By the way, FQL doesn't have such INNER JOIN.
Multi-query:
Evaluates a series of FQL (Facebook Query Language) queries in one call and returns the data at one time.
This method takes a JSON-encoded dictionary called ''queries'' where the individual queries use the exact same syntax as a simple query. However, this method allows for more complex queries to be made. You can fetch data from one query and use it in another query within the same call. The WHERE clause is optional in the latter query, since it references data that’s already been fetched. To reference the results of one query in another query within the same call, specify its name in the FROM clause, preceded by #.
For example, say you want to get some data about a user attending an event. Normally, you’d have to perform two queries in a row, waiting for the results of the first query before running the second query, since the second query depends on data from the first one. But with fql.multiquery, you can run them at the same time, and get all the results you need, giving you better performance than running a series of fql.query calls. First, you need to get the user ID and RSVP status of each attendee, so you’d formulate the first query – query1 – like this:
*
"query1":"SELECT uid, rsvp_status FROM event_member WHERE
eid=12345678"
*
Then to get each attendee’s profile data (name, URL, and picture in this instance), you’d make a second query – query2 – which references the results from query1. You formulate query2 like this:
"*
query2":"SELECT name, url, pic FROM profile WHERE id IN (SELECT uid
FROM #query1)
*"
https://developers.facebook.com/docs/technical-guides/fql
I am not entirely sure if this fixes your problem, but it seems that the parameter is "q", not "queries":
params.putString("q", jsonFQL.toString());
...if you take a look at the Facebook docs:
https://developers.facebook.com/docs/technical-guides/fql
Could be possible that they changed it recently, although it is deprecated so i dont think they will put much effort into it.
This nested query you placed
SELECT sender,body FROM unified_message WHERE thread_id IN (SELECT thread_id FROM unified_thread WHERE folder = 'inbox' AND unread=1) AND unread=1
should work. If it doesn't, consider filing a bug.
Breaking it down,
SELECT thread_id FROM unified_thread WHERE folder = 'inbox' AND unread=1
Should give you the thread ids for threads with unread messages. The only catch here is that unified_thread doesn't necessarily return all threads even with LIMITapplied. So what you did here was good (as long as the unread response set is small enough)
If at this point, the numbers aren't matching what you have, it doesn't make sense to move further in the query. File a bug.
The larger query
SELECT sender,body FROM unified_message WHERE thread_id IN (SELECT thread_id FROM unified_thread WHERE folder = 'inbox' AND unread=1) AND unread=1
Checks all messages within the thread, so as long as your thread ids are valid and correctly counted then there is nothing to worry about here.
Ensure you are getting the correct count of unread threads first If not, as I said before, file a bug.
So that with this query
SELECT thread_id, participants, link FROM unified_thread WHERE folder = 'inbox' AND unread
Cross check that the participants and links match what you have in your inbox.
Related
Android Greendao - group and order by
I'm using GreenDAO in my project. I have a chats table which contains all the messages. I want to group by the chat_id and order the messages in descending order by the timestamp of the message. so what I'm trying to get is a list that contains the most recent message of each chat the user has. this is the code I'm using: Chats.queryBuilder() .orderDesc(ChatsDAO.Properties.TimeStamp) .where(ChatsDAO.Properties.UserId.eq(user_id)) .where(new WhereCondition.StringCondition("1 GROUP BY chat_id")) .list(); but still, the code above gives me a list which contains the first message of each chat, instead of the recent message. is there any way to make a raw query using greenDAO and select what I want?
You can make a raw query using GreenDAO as follow. Also, check the link Query<User> query = userDao.queryBuilder().where( new StringCondition("_ID IN " + "(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)") ).build();
Passing special characters (') in DB query
So i have a data base and in the app while the user searches for something with the ' character, like "wendy's house", i send a query with the WHERE as "wendy's house" and here is where it crushes. I would like to know please what should i do with the string in order that ill be able to send it in the query and the result the user gets will stay unharmed. Thanks in advance.
Here you have an answer how to escape the apostrophe in your SQL: INSERT INTO Person (First, Last) VALUES ('Joe', 'O''Brien') /\ right here Or SELECT First, Last FROM Person WHERE Last = 'O''Brien' https://stackoverflow.com/a/1912100/2065587
SQL Query for timestamp
I had following Table CREATE TABLE Customer ( `Name` varchar(7), `Address` varchar(55), `City` varchar(15),`Contact` int,`timestamp` int) ; INSERT INTO Customer (`Name`,`Address`, `City`, `Contact`,`timestamp`) VALUES ('Jack','New City','LA',79878458,456125), ('Joseph','New Lane23','LA',87458458,794865), ('Rosy','Old City','Paris',79878458,215125), ('Maria','New City','LA',79878458,699125), ('Jack','New City','LA',79878458,456125), ('Rosy','Old City','Paris',79878458,845125), ('Jack','New Main Street','New York',79878458,555525), ('Joseph','Near Bank','SAn Francisco',79878458,984521) ; I want to get all customer record with highest timestamp without duplication.
Try the following. select name,max(timestamp),Address,City,Contact from Customer group by name
I want to get all customer record with highest timestamp without duplication. Use DISTINCT operator and ORDER BY clause like select distinct `Name`,`Address`, `City`, `Contact`,`timestamp` from customer order by `timestamp` desc; In that case you can use JOIN query like select t1.* from customer t1 join (select Name, max(`timestamp`) as maxstamp from customer group by Name) xx on t1.Name = xx.Name and t1.`timestamp` = xx.maxstamp;
Try this: SELECT * FROM `customer` group by name,Address,City,Contact,timestamp order by timestamp desc
I'm joining the Customer table with itself, the condition c1.timestamp<c2.timestamp on the join clause combined with c2.timestamp IS NULL will make sure that only the latest record for each person is returned. I put DISTINCT because on your sample data there are two records for Jack with the same timestamp: SELECT DISTINCT c1.* FROM Customer c1 LEFT JOIN Customer c2 ON c1.Name=c2.Name AND c1.Contact=c2.Contact -- you might want to remove this AND c1.timestamp<c2.timestamp WHERE c2.timestamp IS NULL ORDER BY Name, Address Please see a fiddle here.
Android Cursor select parameter for SMS DB querying
I am trying to get all SMSes from and to a single address. So while using a Cursor to scan the DB, I tried to use select. But, no values were returned. I suspect that this was caused because the numbers in the "address" colum in the DB were containing space and/or hyphens (-). My question is that can I make a query to ignore spaces and hyphens in the string? P.S.: the address I have has been trimmed down to not include spaces and hyphens, and that is unchangeable as per my requirements.
I came across the same situation and tried below method.(not yet sure,was it a proper solution or not! :) ) So, Query all conversations from conversation table take a loop and go through all results.For each: take the address field and remove unwanted character to make it like the number format you have compare with number you want conversation for : if found => break you will have the thread-id for the number you are searching sms of,at the end of loop. Now, now collect message id of all messages under that thread seperated by type:"sent" and "inbox" Then you can use those array of id to gather messages from "sent" and "inbox" table of ContentProvider. I know,the process is bit longer but gave me satisfactory result. :) Hope it helps.
SQLite query: selecting the newest row for each distinct contact
I'm working with the Android SQLite db, and I have a table with messages in it. Each message has a ContactId. I need to get a list of the newest message associated with each ContactId. My query looks like this so far: SELECT * FROM messages GROUP_BY ContactId HAVING ( COUNT(ContactId) = 1 ) ORDER_BY MessageTime DESC However when I run the query I get this exception: near "ContactId": syntax error: , while compiling: SELECT * FROM messages GROUP_BY ContactId HAVING ( COUNT(ContactId) = 1 ) ORDER_BY MessageTime DESC Here's the table definition in case it helps: create table messages (_id integer primary key autoincrement, ContactId text not null, ContactName text not null, ContactNumber text not null, isFrom int not null, Message text not null, MessageTime int not null);
NOTE: My answer below does not appear to be working as of SQLite 3.7.5, I suggest using the "JOIN" query suggested by Larry. You are close. What you need to do is sort all the records first, using a subquery table, and then group them. The values that are returned in the result set will be from the last row in each group. So you actually want newer messages to appear at the bottom if you are trying to get the newset message. The "GROUP BY" already ensures you get one row per ContactId. SELECT * FROM (SELECT * FROM messages ORDER BY MessageTime) GROUP BY ContactId The HAVING clause is not needed. I haven't used it before but according to the docs the HAVING clause will discard whole groups that don't match, but it doesn't sound like you want any groups discarded, you want results from every ContactId. Also note there is no underscore in "ORDER BY" or "GROUP BY".
Here are two ways to do it. This query builds a list of the most recent times for each user, then JOINs that back to the message table to get the message information: SELECT M1.* FROM messages M1 JOIN (SELECT ContactId, MAX(MessageTime) AS MessageTime FROM messages GROUP BY ContactId) M2 ON M1.ContactID = M2.ContactID AND M1.MessageTime = M2.MessageTime; This query does something slightly different. It looks at each message and asks if there exists any later message for the same contact. If not, the row must be the most recent one: SELECT M1.* FROM messages M1 WHERE NOT EXISTS (SELECT * FROM M2 WHERE M2.ContactID = M1.ContactID AND M2.MessageTime > M1.MessageTime)