0

I am using Google API to get information about an authenticated user. I can get the basic profile information, such as the ID and the full name. From the profile information, I can get the URL to the picture:

var plusMeUri = new Uri($"https://www.googleapis.com/plus/v1/people/me?key=<APP-ID>&access_token=<ACCESS-TOKEN>");

string userResponse = await HttpClient.GetStringAsync(plusMeUri);

JObject userObject = JObject.Parse(userResponse);

    ...

var imageObject = userObject.GetValue("image") as JObject;

var pictureUrl = imageObject.GetValue("url").Value<string>();

var pictureUri = new Uri(pictureUrl);
string uri = $"{pictureUri.Scheme}://{pictureUri.Host}{pictureUri.AbsolutePath}";

var pictureRequest = new HttpRequestMessage(HttpMethod.Get, uri);
pictureRequest.Headers.IfModifiedSince = <previous-timestamp>;

HttpResponseMessage pictureResponse = await HttpClient.SendAsync(pictureRequest);

if (pictureResponse.StatusCode == HttpStatusCode.NotModified)
     // No need to handle anything else
     return;

Question

I do not want to download the user's picture if it has not changed. This is why I am using the IfModifiedSince property. It does work with Facebook's API but it does not seem to work with Google's. How can I make it work?

Kzryzstof
  • 7,688
  • 10
  • 61
  • 108

1 Answers1

1

From the information given, it seems like what you're trying to do is determine whether the image you're downloading/about to download is the same image as you've downloaded before. After looking at the Google+ API docs, it looks like the header you've been using isn't officially (at least not obviously) supported by their APIs.

But this is not the only way we can determine whether the image has changed or not (in fact, date last modified isn't necessarily the best way to do this anyway). Alternative methods include:

1) diffing the two images

2) checking the url (if we can assume different resources have different urls)

1 is likely the most accurate but also likely the least efficient, so I'll leave that to you to solve if you decide to go that route. I think the most promising is #2. I went ahead and played around with the API a little bit and it looks like the image.url field changes when you update your profile picture.

For example, here are my last two Google+ profile picture URLs:

As such, instead of waiting for the response from the server and checking its header to decide whether the image has been updated or not, you may be able to short-circuit the entire HTTP request by simply checking whether the last image you pulled down was from the same url or not. If it was from the same URL, it's likely you've already acquired that image otherwise you may not have it so should incur the cost of downloading anyway.

In this case, your code would read something like:

var imageObject = userObject.GetValue("image") as JObject;
var pictureUrl = imageObject.GetValue("url").Value<string>();

if(pictureUrl != <previous-picture-url>)
{
    // insert get new picture logic here...
}
SIRHAMY
  • 157
  • 1
  • 9
  • This is definitely something that can work but I would like to avoid assuming that the file name is necessarily different... – Kzryzstof Oct 17 '18 at 15:32
  • I get the hesitance to rely on filename as a measure of uniqueness, but I'm not sure there's a better way besides image diffing yourself. The only data we really have is Last-Modified (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) and the URL. Last-Modified is flakey cause (at least the Google+ API) doesn't declare how it sets that on its side (does it only happen at set time or at cache/shard time?) and it's suboptimal because it requires a DL to even get that info. By using URL, we at least know when it probably hasn't changed and worst case incur the DL. – SIRHAMY Oct 17 '18 at 17:57
  • My own (rather limited) explorations have shown that the URLs do change when a different image is uploaded and this is supported by the explorations of others like https://stackoverflow.com/questions/42241699/do-the-google-profile-picture-urls-returned-by-the-google-api-change?rq=1. We, again, are relying on something that isn't specifically declared in the API docs, but it seems reasonable the the service would continue to host different resources at different URIs and we have data points to show that this was/is the case. – SIRHAMY Oct 17 '18 at 17:59
  • I will go down this path if there is not any other option :) – Kzryzstof Oct 17 '18 at 18:02