2

I'm using the following approach to return a Facebook user's music preferences:

//FIXME: Fetch results in a single operation
val likes = facebook.likeOperations().music
val artists = ArrayList<Artist>()
for (musicLiked in likes)
{
    val musicProfile = facebook.fetchObject(musicLiked.id, Page::class.java, "id", "name", "genre");
    artists.add(Artist(name = musicProfile.name, genre = musicProfile.genre))
}

The above approach won't scale, since we have an additional network operation for each artist the user likes.

I tried:

I tried using facebook.likeOperations.music however this doesn't fetch genre.

Question:

I would like to use facebook.fetchObject with a query that returns a PagedList. How to do this?

(No need to post example code in Kotlin if you prefer or are more familiar with Java - I'll be happy with information in any language).

Jasper Blues
  • 28,258
  • 22
  • 102
  • 185
  • Are you optimising prematurely? – hd1 Oct 28 '15 at 23:41
  • @hd1 No, have you heard of 'n+1 select'? That's what this is. – Jasper Blues Oct 29 '15 at 02:32
  • 1
    @approxiblue Sounds great, but is there not a way to invoke the fetchObject method and map to a collection instead of a single object? Many queries return collections, so I assumed it was possible somehow, and just didn't know how due to unfamiliarity with the FB template / kotlin. – Jasper Blues Oct 29 '15 at 02:49

2 Answers2

1

Facebook api uses "fields" parameter in requests to return custom fields for objects. This parameter can be also used for liked music rest request.



    me/music?fields=id,genre,name

above link will return all liked music with id, genre and name of the artist/group. Unfortunately FacebookTemplate does not have method which will apply for your needs. The method Facebook.likeOperations() returns instance of the LikeTemplate class which has constant PAGE_FIELDS with value



    private static final String PAGE_FIELDS = "id,name,category,description,location,website,picture,phone,affiliation,company_overview,likes,checkins";

In above constant you do not have genre field. So you have two ways:

  1. You can simply use facebook rest api with some rest library
  2. You can override FacebookTemplate and return your own implementation of LikeTemplate as result of the likeOperations() method. You implementation of the LikeTemplate class should have different value in mentioned constant (added genre field at the end of the string)

Maybe some one will be more helpful but in my knowledge you do not have other options.

burovmarley
  • 644
  • 3
  • 8
1

Thanks to advice given in @burovmarley's answer, I inspected the source and came up with:

val music = facebook.fetchConnections(userPage.id, "music", Page::class.java,
            PagingParameters(25, 0, null, null).toMap(), "id,name,,genre")
for (musicLiked in music)
{
    println("likes: ${musicLiked.name}, genre: ${musicLiked.genre}")
}

This allows using Spring Social Facebook as an unmodified dependency, and without issuing a pull request, which seem to be fairly slow in processing through the queue at the present time.

Jasper Blues
  • 28,258
  • 22
  • 102
  • 185