This is a common issue on latency when sending several requests (and rate limiting). I have similar issues with my own backend, and it is a symptom of moving towards micro service oriented smaller requests. A common solution is to batch the requests into 1 request. It seems Facebook graph API has this setup for you to use already:
Note you might need to add a little additional logic client side to get around rate limiter.
I assume you are hitting a rate limit which will put your IP on a cool down before allowing new requests. This is likely what is causing your long response time. You will need to experiment with a good request/batch sending to stay within Facebookās limits and minimize latency as well.
Also** cache is your friend. Look into setting up a cache client side, or if you put a server in the middle of these requests you can use redis etc
More information on FB rate limiting:
When the limit has been reached stop making API calls.
Continuing to make calls will continue to increase your call count which
will increase the time before calls will be successful again.
Iāve a similar problem.
My game is in production and since some months, iām having problems for GET facebook photos of āmy friendsā. Iāve more than one friend, and when I try to get all photos, i can get only one. When I request the second photo of my second friend, i receive this response " The request timed out. ". It worked until a few months ago. Since weeks, it doesnāt work anymore. Itās very strange.
My code:
for(....) //my friend list
{
HttpRequest* requestFacebookPhoto = new HttpRequest();
requestFacebookPhoto->setUrl(friendPhotoUrl); //I tested all URLs in Chrome and it works. The url is ok.
requestFacebookPhoto->setRequestType(HttpRequest::Type::GET);
requestFacebookPhoto->setResponseCallback([](HttpClient* client, HttpResponse* response) {
if (!response or response->getResponseCode() != 200) {
//response code is -1, so, when i debug it, it enters to this if
return;
}
//more code below..
});
HttpClient::getInstance()->send(requestFacebookPhoto);
requestFacebookPhoto->release();
}
I tried to make a delay between each request, but it doesnāt work either.
The question is, whatās the solution? because, far as I know, I canāt request all photos in only one request. And if I could, iām sure that it has a limit too. What about if Iāve 1000 friends? haha.
I put a detailed response about batching requests / trying to get around rate limiting. Did you give that a try?
Also, if you have 1000 friends, that is where a server side cache would be beneficial. Users would have their avatar cached at account creation, and there could be a expiration on the cache to make sure there is a current photo, or it can check each time the given user logs on etc. 1000 avatars cached properly could result in a sub 50ms response time.
If I understand this correctly, batching wonāt help with the rate limiting either, besides reducing the network traffic. This is the specific part Iām referring to on that page:
What do we consider an API call?
....
You can also use the Batch API to batch your requests, but note that each sub-request
is its own API call, or even multiple API calls in the case of specifying many ids.
Caching is would be best method to use here.
If a user of an app has 1000 friends, there should never be a need to retrieve all at once. How about you only retrieve what is visible to the user. Imagine itās a list view, and as the user is scrolling through it, you grab the next set of images (only as many as the user can see). You can cache them on the client very easily. For example, in a SQLite table, save the id of each user you received an image for, and the path to that image (do not store the image data in the database). So, in future, you check your SQLite database first to see if the image exists, and if it does, grab that instead of sending off a request to the Facebook API.
You then have a choice to update photos every X period of time, or if your app allows the user to click on one of their friends, then that would be a perfect time to refresh the photo (itās unlikely your user is going to click all 1000 friendsā¦)
For sure, I was just throwing some ideas around. I donāt use Facebook API or retrieve FB avatars in any of my projects. Just what I came up with from some 2minute searches in the actual documentations. I like to batch my requests to my API where possible for network reasons like you mentioned, but since the rate limiter is integrated into the FB batch endpoint, it might not help the rate limit side. And yes, when in doubt ā¦ cache!
Also good point on the āonly pull what is necessaryā. Imagine if Instagram pulled their entire list every time you pulled up a profile ā¦ lazy loading
I think avatars cached isnāt the solution. The problem that Iāve is that the server give me a ātime-outā response when I request the second avatar. I could cached the avatars but when I try to request these again, I will have the same problem.
Also, I donāt like to store images or personal information in my own database. Maybe iām violating some privacy term. I store only his/her facebook id in my own db.
when you say time outā¦ is this a time out on your own request, or from FB side? If your request has a 10ms time out, it might not give FB enough time to respond etc. But if FB is timing out, you should reach out to FB dev community not cocos.
for(....) //my friend list
{
HttpRequest* requestFacebookPhoto = new HttpRequest();
requestFacebookPhoto->setUrl(friendPhotoUrl); //I tested all URLs in Chrome and it works. The url is ok.
requestFacebookPhoto->setRequestType(HttpRequest::Type::GET);
requestFacebookPhoto->setResponseCallback([](HttpClient* client, HttpResponse* response) {
if (!response or response->getResponseCode() != 200) {
//response code is -1, so, when i debug it, it enters to this if
return;
}
//more code below..
});
HttpClient::getInstance()->send(requestFacebookPhoto);
requestFacebookPhoto->release();
}
It seem to be a FB problem, not mine. But I asked in the community and nobody gives me a solution. Maybe there are some limitation in the API or whateverā¦ itās strange.