Accessing Photo Albums in Facebook
Hello everyone and welcome to a new episode of the Facebook integration for Windows Store App series. Christophe Nasarre, a French Premier Field Engineer is explaining how to list the photo albums of a Facebook profile. He will detail the photo enumeration and the paging mechanism in the next episode.
For your convenience, here’s the video timeline:
[0:20] App demo to view Facebook albums and photos
[1:40] Facebook documentation for Albums
[2:05] Changes to the LoginAsync code for user_photo permission
[2:26] Graph Explorer session for Albums query and corresponding Json response
[3:57] C# mapping for Albums
[5:30] Code to get the Albums and Json parsing tricks
[8:12] C# pattern to asynchronously update the data bound UI
[10:12] details of asynchronous cover photo album retrieval
Preview of the expected result
Here is what I want to achieve:
When the user clicks the Albums button, its existing Facebook photo albums are listed with their name and cover picture. When an album is selected, its photos are listed. Facebook is returning only a subset of photos and the user can navigate between chunks with the Previous/Next buttons.
Exploring the album Facebook API
As explained in the previous episode, the first step is always to go to the Facebook documentation and start a session in the Graph Explorer to figure out how to get the information you need. In this case, I’m interested in the Album endpoint
The required permissions are “user_photos”
I will have to add it to the login code in the application
var loginUrl = FbClient.GetLoginUrl(new
{
client_id = FacebookAppID,
redirect_uri = WindowsStoreAppSID,
// MS-CN: adding access to the required features
// user_photos: list of albums + their pictures
scope = "user_photos",// Facebook permissions
display = "popup",
response_type = "token"
});
So, open a Graph Explorer session and select the right permission
And submit a GET /me/albums query
The Json result is a list of albums under a “data” root node
Click on the id value of the first album to get an easy to read view of the field describing an album
For my App, I’m only interested in the name, count, privacy, type and the cover_photo fields. Well… I should not forget the id because this is how I’ll be able to get its photos!
The C# side of the story
I’m storing these album descriptions into a collection of Album C# class that is bound to a ListView
It is important to note that only the id field is mandatory, the others might be empty; i.e. not defined in the Json. This is why it is so important to always check if a field is present before trying to get its value. Here is the stripped down code for the GetAlbumAsync method in charge of sending the GET request and of parsing the return Json:
List albums = new List();
dynamic albumsTaskResult = await FbClient.GetTaskAsync("/me/albums");
var result = (IDictionary<string, object>)albumsTaskResult;
var data = (IEnumerable<object>)result["data"];
foreach (var item in data)
{
var album = (IDictionary<string, object>)item;
// now you can retrieve data from the dictionary above
string id = (string)album["id"];
string name = string.Empty;
string coverPhotoId = string.Empty;
int count = 0;
string privacy = string.Empty;
string type = string.Empty;
if (album.ContainsKey("name"))
name = (string)album["name"];
if (album.ContainsKey("cover_photo"))
coverPhotoId = (string)album["cover_photo"];
if (album.ContainsKey("count"))
count = Convert.ToInt32(album["count"]);
if (album.ContainsKey("privacy"))
privacy = (string)album["privacy"];
if (album.ContainsKey("type"))
type = (string)album["type"];
Album newAlbum = newAlbum(id, name)
{
Count = count,
CoverPhotoId = coverPhotoId,
Privacy = privacy,
Type = type
};
albums.Add(newAlbum);
}
As you can see, all albums are retrieved in one asynchronous call; not including the cover photo itself: just its id is stored in the CoverPhotoId property. Each cover photo will be asynchronously fetched in two steps. The first one is to get its URI
async private void albumBT_Click(object sender, RoutedEventArgs e)
{
List<Album> albums = await _fbHelper.GetAlbumsAsync();
if (albums == null)
return;
// create a listview and change its data source to the list of albums
gvAlbums.ItemsSource = albums;
foreach (var album in albums)
{
// get the uri
Uri coverUri = await _fbHelper.LoadAlbumCoverPhotoUriAsync(album.CoverPhotoId);
if (coverUri == null)
continue; // some albums might not have cover photo
// get the corresponding picture
album.CoverPhotoImage = newBitmapImage(coverUri);
}
}
And the second step is done implicitly for you by the BitmapImage which will download asynchronously the bits of the picture: this is how the cover photos are appearing magically after the name of all albums are visible on the screen.
Note that the first step to get the URI requires a call to the Facebook SDK just passing the id of the cover photo
dynamic albumsTaskResult = await FbClient.GetTaskAsync("/" + coverPhotoId);
var result = (IDictionary<string, object>)albumsTaskResult;
var pictureUri = (string)result["source"]; // the "picture" entry is a thumbnail
if (pictureUri != null)
uri = newUri(pictureUri);
The string URI is the value of the source key in the returned Json and the picture key is just a thumbnail that might be too small for your needs.
The next episode will cover how to retrieve the photos of an album and how to handle pagination when a large number of photos are available.
Happy Coding!