I am using Retrofit2 in my application. My problem is that I have a group of persons in my list and all these persons are to be continuously monitored.
Monitoring in the sense that I need to make a retrofit call for each person ,to obtain the real time data of that person.
For example,
Consider person 1 :
My initial request call will be with the following data.
{
"patientId" : "qwerty1",
"time": ""
}
Response is:
{
"data" : [],
"updated_time" : "16519644"
}
Next request for person 1 :
{
"patientId" : "qwerty1",
"time": "16519644"
}
and this repeats. Server side coding is in such a way that only a set of 20 data are provided as response for our request. So to obtain continuous data set we need to make repeated call. I need to do this process for "n" number of persons in real time. Also I need to update UI when there is a response. I am really confused with the concept of sending retrofit request in a loop. Please suggest a way.
Related
Is there any way to order the subscription list of Youtube channels by recently subscribed?
youtube
.subscriptions()
.list("snippet")
.setOrder("")// relevance, unread, alphabetical
.setMaxResults((long) 1000) // it is not affecting, the max limit is 50
.setMine(true)
.execute();
According to documents, I can only get max 50 items at a time, and I have only three order type parameters relevance, unread, alphabetical.
But I need to reach the channel I subscribed lastly. I would be really appreciated it if anybody helps me to handle this.
Thanks in advance!
According to the docs, you have the following parameter at your disposal:
myRecentSubscribers (boolean)
This parameter can only be used in a properly authorized request. Set this parameter's value to true to retrieve a feed of the subscribers of the authenticated user in reverse chronological order (newest first).
Note that this parameter only supports retrieval of the most recent 1000 subscribers to the authenticated user's channel. To retrieve a complete list of subscribers, use the mySubscribers parameter. That parameter, which does not return subscribers in a particular order, does not limit the number of subscribers that can be retrieved.
That is: do insert something like .setMyRecentSubscribers(true) in the sequence of setters of your code above. (Also you may remove the setChannelId setter call, since, by requiring from you to be authorized to invoke this endpoint, the API already knows the channel to which your call is referring to.)
Note also that the parameter's maxResults maximum value is 50. To receive only the most recent subscriber have .setMaxResults(1) in the setter sequence above.
If your want to obtain the list of all your subscriptions then there's the following parameter:
mine (boolean)
This parameter can only be used in a properly authorized request. Set this parameter's value to true to retrieve a feed of the authenticated user's subscriptions.
Have .setMine(true) (without .setChannelId) in your setters sequence.
You will have to invoke repeatedly the API's endpoint to get all of your subscriptions, since this endpoint provides paginated result sets. Upon obtaining all those subscriptions, sort them by snippet.publishedAt.
If you're only interested to obtain the most recent channel to which to have subscribed, instead of the sort algorithm, is sufficient to use the max algorithm (O(n) instead of O(n log n)) on the same property.
For an example of how to implement pagination in your code, have a look at some of the sample code provided by Google itself.
As I understand from your question, you want to check if you are following a specific youtube channel with help of Youtube Data API V3.
For that it is mentioned in the document that you can use forChannelId parameter.
Also Youtube Data API has a playground to let you see the results of your query. You can simply put a channelId in forChannelId field and result will return an empty array if you are not subscribed specified channel or result will return the data of that specified channel if you are subscribed to it.
You can do a simple request from your Java app to get results. In this code example I'm checking if authorized youtube API user is subscribed to Firebase Youtube Channel or not.
SubscriptionListResponse response = request.setForChannelId("UC_x5XG1OV2P6uZZ5FSM9Ttw")
.setMine(true)
.execute();
And response will include details of specified channel in the request you will make. I also share response of the request I shared above.
{
"kind": "youtube#SubscriptionListResponse",
"etag": "zCQ7lTwIBgdyVsQmbymEu-fUgjU",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#subscription",
"etag": "A-G_B0BnSqn7XtJi7BgHJEk9L3Q",
"id": "uTEDDg6jpPBwnsim9moHkataEljshwFopudOgIy34nk",
"snippet": {
"publishedAt": "2020-07-08T14:02:43.789000Z",
"title": "Google Developers",
"description": "The Google Developers channel features talks from events, educational series, best practices, tips, and the latest updates across our products and platforms.",
"resourceId": {
"kind": "youtube#channel",
"channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw"
},
"channelId": "UCC77fYySvfP7p-6QGaa-3lw",
"thumbnails": {
"default": {
"url": "https://yt3.ggpht.com/-Fgp8KFpgQqE/AAAAAAAAAAI/AAAAAAAAAAA/Wyh1vV5Up0I/s88-c-k-no-mo-rj-c0xffffff/photo.jpg"
},
"medium": {
"url": "https://yt3.ggpht.com/-Fgp8KFpgQqE/AAAAAAAAAAI/AAAAAAAAAAA/Wyh1vV5Up0I/s240-c-k-no-mo-rj-c0xffffff/photo.jpg"
},
"high": {
"url": "https://yt3.ggpht.com/-Fgp8KFpgQqE/AAAAAAAAAAI/AAAAAAAAAAA/Wyh1vV5Up0I/s800-c-k-no-mo-rj-c0xffffff/photo.jpg"
}
}
}
}
]
}
I've read that Get requests should be idempotent.
I'm making an android app with a list of articles. Both guest and authenticated users can view a list of articles, but authenticated also get favorited status.
To make a request idempotent, the authenticated user should request both /articles and a second request to get the favorite status of this article.
How professional developers make these things? What is the best practice?
I see 3 ways:
Return a combined result based on the user. for guests favorited: 0, for authenticated if favorited, favorited: 1
GET /articles (statefull)
[
{
"id":1,
"title":"First Article",
"favorited":1
},
{
"id":2,
"title":"Second Article",
"favorited":0
},
{
"id":3,
"title":"Third Article",
"favorited":1
}
]
Return stateless and make ​additional request to check the favorited status for this article ids if authenticated.
GET /articles (stateless)
[
{
"id":1,
"title":"First Article"
},
{
"id":2,
"title":"Second Article"
},
{
"id":3,
"title":"Third Article"
}
]
if authenticated get favorite statuses for article id 1, 2 and 3
GET /favorites?id=1,2,3
[
{
"id":1,
"favorited":1
},
{
"id":2,
"favorited":0
},
{
"id":3,
"favorited":1
}
]
Return stateless. After login user need to request endpoint to get all favorited ids, save them in the local client, and on every item display check from local if post id is favorite. Note some users have 300+ favorited articles
After login get all favorited ids, save in client.
GET /myFavoriteArticleIds
[
1,
3,
5,
9,
17
]
And then make stateless requests
GET /articles (stateless)
[
{
"id":1,
"title":"First Article"
},
{
"id":2,
"title":"Second Article"
},
{
"id":3,
"title":"Third Article"
}
]
You should be using only one API request GET /api/articles. Authorized requests should have the Authorization header value. Based on that the response could be filtered while serializing the result object.
We can have customized responses from API based on the Authorization header.
Refer to Baeldung - https://www.baeldung.com/jackson-serialize-field-custom-criteria
It would perhaps help to review the definitions of safe and idempotent as found in RFC 7231. The semantics of GET are safe, which means that all of the constraints of idempotent are satisfied, and some others.
In summary, safe means read-only.
But it doesn't tell you anything about representations, or resource design.
How professional developers make this things? What is best practice?
Think about how you would design a web site? One answer would be to have a page for anonymous users, and then a different page for administrators (which includes the extra information that the administrators need). The second page would be locked down so that only authorized users can get at it (which has some interesting implications for caching).
The same basic principles hold for an API.
To distinguish the difference between guest and authenticated cases, I would recommend you to use namespaces for all APIs.
Ex:
For authenticated users,
/api/articles - list of articles along with favorites
/api/articles/$article_id - single article information along with favorited time etc
For guest users,
/guest_api/articles - only the list of articles
/guest_api/articles/$article_id - only the article information
Based on the user type, the favorited flag can be returned in response.
User type can be passed a query parameter.
Example: GET /api/v1/articles?user=guest
I am developing an e-commerce android application. am stuck in a situation, i don't know how to handle the situation. That is,
How can i post dynamic json values in Retrofit. For example
{
"type":"1",
"typeId":"10",
"userId":"15",
"filters":{
"price":"from-to",
"attribute_code":"values",
"...":"....",
"...":"...."
}
}
in this the "filter" is another object in the main json. the values in "filter" json is dynamic like sometime it may have "price", "size" or sometimes it may have "price" only or some times it may have "price","size","offers" etc..
How can we handle this circumstance..
Thanks
My Android app is making two GET calls to my Server API. In the first one, is this, where parameter code is a 256 char String.
$.getJSON( myServerEndpoint, {
action: "doStuff1",
username: $("#username").val(),
code: my256charString,
format: "json"
})
.done(function( data ) {
doStuff2Response(data);
});
The second one is this, where parameter code is a 5120 char String. Both reach the same server endpoint.
$.getJSON( myServerEndpoint, {
action: "doStuff2",
username: $("#username").val(),
code: my5120CharString,
format: "json"
})
.done(function( data ) {
doStuff2Response(data);
});
When I call both of them from the same device and same user connected to WiFi or most mobile data providers, it works perfectly.
However, when I connect from a Vodafone data connection, the second request never reaches the server. I cannot find any other explanation than that there is a limit on the length of the parameters with Vodafone.
Any ideas or solutions?
OK, so here it goes. First, read this: What is the maximum length of a URL in different browsers?
Yes, there's a limit in the length of the "URL", but someway I don't know how to explain why it is happening only for vodafone. Plus, I don't even know how the request pass through their servers anyways.
As for the solution, you should consider changing from GET request to POST request when the payload is too big.
Quick solution: Base64-encode the code part of the message. Downside: you must decode on the server. This is a standard function in most languages though.
If you're already using Base64 or somesuch cypher, what about Blobs? https://developer.mozilla.org/en-US/docs/Web/API/Blob
chromano's suggestion is spot-on too, just switch to POST and you will definitely get an unlimited Post Body. Downside: Have to JSON.stringify and JSON.parse for yourself, and if you want to expose this URL to a user (say as a link to share) it now can't carry the same information (URL's are GET requests).
I have a json file on server:
{"images":[
{"url":"...", "likes":"123"},
{"url":"...", "likes":"234"},
{"url":"...", "likes":"345"}
]}
I get the json file on android read it, but if someone likes a picture i want to change the value of the first picture from 123 to 124, is this possible and how can i do this?
The whole point is to change a json value on server,from client side.
Also if this isn't possible how can i make this happen?
Also if i want to get the Top50 rated pictures,how can i sort them and get only the 50 picture,without getting all pictures and sorting them on android ?
Which one is better,initializing the Top50 images,when the user starts the app,or when the user click on the button Top50.I assume that if its when he click the button,there might be some performance issues server side?
My other idea is to have a function server side,which every 10 min,executes automatically and gets the Top50 rated and makes something like json file.So it all happens server side automatically.
To make this happen, client should expose some interface, i.e. function that will allow to modify file on server side. The interface and implementation of this function greatly depends on server itself, i.e. which protocols it handles, what built-in or external modules it supports, which languages are supported, etc... For example, the classic scenario is using apache as HTTP server, CGI enabled, and write CGI function in perl. So, in this case interface would look like http://server.name/like.cgi?image=image123.
How to modify the values on the server ?
For this every like of a photo should be a post request of this sort.
{
"data": [
{
"image_id": 3133456,
"likes": 343
},
{
"image_id": 3133456,
"likes": 343
}
]
}
On parsing this request server updates the corresponding image's like on the server.
How to get the top 50 rated/liked images from the server ?
Again you send a get request to such a url
http://server.getsomething.com/getTop50Images
On server side
On receiving such a request you make a query on the table in your database something like this
select image_id , image_url, likes from image_table limit 50 ORDER BY likes ASC
Now getting those query results and returning them as a json would not be a performance hit until you have huge bulk of data. like some million rows may be in your database.
Response can be something like this
{
"result": [
{
"image_id": 3133456,
"likes": 34400,
"url": "http://flickr.com/someimage"
},
{
"image_id": 3133456,
"likes": 34380,
"url": "http://flickr.com/someimage"
}
]
}
You still avoid using a database yourself but can lease it from clouds services like parse.
However if you won't be using those services then you can take a look at ftp packages for js. Like the neo JavaScript library by apache.
But still a good choice will be to go with the database approach (is quiet simpler).