Facebook Module
Using the Facebook module you can let your application users authorize themselves with their Facebook ID. An accessToken is stored on the authenticated user object.
Configuration
Facebook Scope
The scopes that you want the user to authorize. Default value here is “email, user_posts” which you should leave like it is until more functionality is added to this module. Read more about possible permissions here.
Facebook App Secret
With the Facebook app secret it’s possible to request data which the user of the Facebook app has approved. If you want to access this data you have to insert the app secrets here.
Facebook App ID
The ID of the Facebook app where you want your users be authorized against. The default value is the ApiOmat Facebook app ID; if you have your own Facebook app, you may enter this one here.
Usage
After setting the configuration parameters, you may call the following URL in your app to start authentication for a user:
https://apiomat.org/yambas/rest/modules/Facebook/spec/YOURAPPNAME/auth?\memberId=USERID&usedSystem=SYSTEM
If you develop for android or iOS you have to use a WebView to call the URL.
You have to replace YOURAPPNAME with the name of your app, the USERID with the ID of your current User and SYSTEM with the system information. To fetch the UserID you can use this:
int start = user.getHref().lastIndexOf("/");String id = user.getHref().substring(start + 1);
You can easily access the system information by calling the attribute “system” from the class “User”. So if you are programming with java it could look like this:
webview.loadUrl("http://apiomat.org/yambas/rest/modules/Facebook" +"/spec/TestApp/auth?memberId=" + id + "&usedSystem=" +User.system);
The Facebook site is presented to the user asking him if the requesting app (with the ID set in the configuration) may get access to the scopes (set in the configuration) after he logged in. If the user clicks OK the authentication starts, otherwise it is cancelled.
If authentication was successful, the user object will have an additional field accessToken on server side. To fetch this one you have to do a simple reload of the user, so your code may look like this:
callAuthURL();// do other things// later on get the actualized user objectuser.loadMeAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { Log.d("MyActivity", "accessToken: " + user.getAccessToken()); } }});callAuthURL();// do other things// later on get the actualized user object[user loadMeAsyncWithFinishingBlock:^(NSError *error) { NsLog(@"accessToken: %@ " , [user getAccessToken]);}];var user = new Apiomat.User();callAuthUrl();user.loadMe({ onOk : function() { console.log("accessToken: " + user.getAccessToken()); }, onError : function(error) { }});var user = apiomat.User(); callAuthUrl();
Using these values you can access Facebook API without doing a rather complicated OAuth handshake by yourself.
But you can also set the accessToken from your client by calling the following method on your user object:
user.setAccessToken("<the_token>");[user setAccessToken:@"<the_token>"];user.setAccessToken("<the_token>");user.set({"accessToken", "<the_token>"})
Read here (android) or here (iOS) how you get the accessToken from the native Facebook client libraries.
If you set the accessToken by your own you don’t must set the “Facebook App Secret” in your module config.
If you added the Facebook module to your app setup, you will be able to work with Facebook models like with ‘normal’ models. The following models will handling the communication with Facebook:
-
FBUser — represent the user in facebook
-
FBPost — represent a post in facebook
-
FBComment — A comment in facebook graph API
-
FBLike — represents a like in facebook system
Working with posts
You can get your own posts by loading the list of posts from a FBUser object. In the following example we’re getting our own posts.
final FBUser me = new FBUser( );// You have to save the model first, because you need a valid href from the serverme.saveAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { // Get the last 25 own posts me.loadPostsAsync("", new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { List<FBPost> posts = me.getPosts(); //Print out the posts for ( FBPost fbPost : posts ) { Log.d("MyActivity", "Message: " + fbPost.getMessage( ) ); } } }); } }});AOMFBUser *me = [[AOMFBUser alloc] init];// You have to save the model first,// cause you need a valid href from the server[me saveAsyncWithBlock:^(NSError *error) { // Get the last 25 own posts [me loadPostsAsync:@"" andWithBlock:^(NSError *error) { if(error == FALSE) { //Print out the posts for (AOMFBPost *fbPost in [me posts]) { NSLog(@"Message: %@", [fbPost message]); } } }];}];var me = new Apiomat.FBUser( );var loadPostsCB = { onOk : function() { var posts = me.getPosts(); //Print out the posts for (var i=0;i<posts.length;i++) { console.log("Message: " + posts[i].getMessage( ) ); } }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); }};//You have to save the model first, because you need a valid href from the servervar saveCB = { onOk : function() { // Get the last 25 own posts me.loadPosts("", loadPostsCB); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); }};me.save(saveCB);var loadPostsCB = { success: function(model, response, options) { var posts = model.get("posts"); //print out the posts for(var i = 0; i < posts.length; i++) { console.log("Message: " + posts[i].get("Message")); } }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); }}var saveUserCB = { success: function(model, response, options) { model.loadPosts(loadPostsCB); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); }}var me = apiomat.FBUser();//you have to save the model first, because you need a valid href from serverme.save(saveUserCB);FBUser me = new FBUser ();//you have to save the model first in order to get a valid href from serverawait me.SaveAsync ();//get the latest 25 own postsawait me.LoadPostsAsync();IList<FBPost> posts = me.Posts;//print the postsforeach (FBPost post in posts){ Console.WriteLine ("message content: " + post.Message);}
It’s also very easy and straightforward to send a post to your own wall.
FBPost newPost = new FBPost();newPost.setMessage("A test post from api o mat");try { // Send to your own wall newPost.save( );} catch (Exception e) { System.err.println("Error occured: " + e.getMessage());}AOMFBPost *newPost = [[AOMFBPost alloc] init];[newPost setMessage:@"A test post from ApiOmat"];//Send to your own wall[newPost saveAsyncWithBlock:^(NSError *error) { if(error) { NSLog(@"Error occured: %@", [error userInfo]); }}];var newPost= new Apiomat.FBPost();newPost.setMessage("A test post from ApiOmat");// Send to your own wall newPost.save( );var saveCB = { onOk : function() { console.log("saved"); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); }};newPost.save(saveCB);var savePostCB = { success: function(model, response, options) { console.log("post successfully saved"); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); }}var newPost = apiomat.FBPost();newPost.set({"Message", "a test message from apiomat"});newPost.save(savePostCB);FBPost post = new FBPost();post.Message = "A test post from ApiOmat";//send to our own wallawait post.SaveAsync ();
Note: Cause Facebook changes their Graph API it isn’t longer possible to pin a message to the wall of a friend!
Delete a current post:
//...get posts (see above)//Delete object of type FBPostfbPost.deleteAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { // ... } }});//...get posts (see aboove)//Delete object of type FBPost[fbPost deleteAsyncWithBlock:^(NSError *error) {}];//... get posts have a look to the example above//delete object of type FBPostvar deleteCB = { onOk : function() { console.log("deleted"); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); }};newPost.deleteModel(deleteCB);var deletePostCB = { success: function(model, response, options) { console.log("successfully deleted post"); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); }}newPost.destory(deletePostCB);//... get posts have a look to the example above//delete object of type FBPostawait post.DeleteAsync();
You can fetch the comments of a post with the following code snippet:
private void test() { final FBUser me = new FBUser(); me.saveAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { printCommentsOfPostOfUser(me, 0); } } });}private void printCommentsOfPostOfUser(final FBUser user, final int postIndex){ // Now download the list of posts user.loadPostsAsync("", new AOMEmptyCallback() { List posts = user.getPosts(); @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { printCommentsOfPost(posts.get(postIndex)); } } });}private void printCommentsOfPost(final FBPost post) { // Get the comments for the first post post.loadCommentsAsync("", new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null){ List<fbcomment> comments = post.getComments(); for (FBComment comment : comments) { String message = String.format("Comment from %s: %s", comment .getFrom().get("name"), comment.getMessage())); Log.d("MyActivity", message ); } } } });}AOMFBUser *me = [[AOMFBUser alloc] init];[me saveAsyncWithBlock:^(NSError *error) { // Now download list of posts List [me loadPostsAsync:@"" andWithBlock:^(NSError *error) { if(error == FALSE) { // Get the comments for the first post [[me posts][0] loadCommentsAsync:@"" andWithBlock:^(NSError *error) { for (AOMFBComment *comment in [[me posts][0] comments]) { NsLog(@"Comment from %@: %@", [[comment from] objectForKey:@"name"], [comment message]); } }]; } else { NSLog(@"Error occured: %@", [error userInfo]); } }];}];function test() { var me= new Apiomat.FBUser(); var saveCB = { onOk : function() { printCommentsOfPostOfUser(me,0); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; me.save(saveCB);}function printCommentsOfPostsOfUser(var user, var postIndex) { var loadPostsCB = { onOk : function() { var posts=user.getPosts(); printCommentsOfPost(posts.get(postIndex)); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; user.loadPosts(loadPostsCB);}function printCommentsOfPost(var post) { var loadCommentsCB = { onOk : function() { var comments=posts.getComments(); for (index = 0; index < comments.length; ++index) { console.log(comments[index]); } }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; post.loadComments(loadCommentsCB);}function printCommentsOfPost(var post) { var loadCommentsCB = { success: function(model, response, options) { var comments = posts.get("Comments"); for (var i = 0; i comments.length; i++) { console.log(comments[i]); } }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } } post.loadComments(loadCommentsCB);}function printCommentsOfPostOfUser(var user, var postIndex) { var loadPostsCB = { success: function(model, response, options) { var posts = model.get("Posts"); printCommentsOfPost(posts[postIndex]); }, error: function (model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } } user.loadPosts(loadPostsCB);}function test() { var me = apiomat.FBUser(); var saveUserCB = { success: function(model, response, options) { printCommentsOfPostOfUser(model, 0); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } me.save(saveUserCB);}FBUser me = new FBUser ();await me.SaveAsync ();//load list of postsme.LoadPostsAsync ();if (me.Posts.Count > 0){ FBPost post = me.Posts [0]; Console.WriteLine ("content of first post: " + post.Message); await post.LoadCommentsAsync() IList<FBComment> comments = post.Comments; foreach (FBComment comment in comments) { Console.WriteLine ("Comment from " + comment.From.Values ["name"] + ": " + comment.Message); }}
When you want to add a comment to a post do the following things:
private void test() { final FBUser me = new FBUser( ); me.saveAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null){ addCommentToPostOfUser(me, 0, "A comment"); } } });}private void addCommentToPostOfUser(final FBUser user, final int postIndex, final String commentText) { user.loadPostsAsync("", new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null){ FBPost post = user.getPosts().get(postIndex); addCommentToPost(post, commentText); } } });}private void addCommentToPost(final FBPost post, final String commentText){ final FBComment comment = new FBComment(); comment.setPostId(post.getForeignId()); comment.setMessage(commentText); comment.saveAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null){ linkCommentToPost(post, comment); } } });}private void linkCommentToPost(final FBPost post, final FBComment comment) { post.postCommentsAsync(comment, new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { // ... } } });}AOMFBUser *me = [[AOMFBUser alloc] init];[me saveAsyncWithBlock:^(NSError *error) { // download list of posts [me loadPostsAsync:@"" andWithBlock:^(NSError *error) { if(error == FALSE) { // Create a new comment AOMFBComment *comment = [[AOMFBComment alloc] init]; // Set the post id AOMFBPost postWithComment = [me posts][0]; [comment setPostId:[postWithComment getForeignId]]; // add a text [comment setMessage:@"A comment"]; [comment saveAsyncWithBlock:^(NSError *error) { // Also link together [postWithComment postCommentsAsync:comment andWithBlock:^(NSError *error) { if(error) { NSLog(@ "Error occured: %@", [error userInfo]); } }]; }]; } }];}];function test() { var me= new Apiomat.FBUser(); var saveCB = { onOk : function() { addCommentToPostOfUser(me, 0, "A comment"); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; me.save(saveCB);}function addCommentToPostOfUser(var user, var postIndex, var commentText) { var loadPostsCB = { onOk : function() { var post = user.getPosts().get(postIndex); addCommentToPost(post, commentText); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; user.loadPosts(loadPostsCB);}function addCommentToPost (var post, var commentText) { var comment= new Apiomat.FBComment(); comment.setPostId(post.getForeignId()); comment.setMessage(commentText); var commentSaveCB = { onOk : function() { linkCommentToPost(post, comment); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; comment.save(commentSaveCB);}function linkCommentToPost(var post, var comment) { var postCommentsCB = { onOk : function() { console.log("saved"); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; post.postComments(postCommentsCB);}function linkCommentToPost(comment, post) { var postCommentToPostCB = { success: function(model, reponse, options) { console.log("successfully posted comment to post"); }, error: function(model, resposne, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } } post.postComment(comment, postCommentToPostCB);}function addCommentToPost(var post, var commentMessage) { var comment = apiomat.FBComment(); comment.set({"PostId", post.get("foreignId")}); comment.set({"Message", commentMessage}); saveCommentCB = { success: function(model, response, options) { linkCommentToPost(comment, post); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } } comment.save(saveCommentCB);}function addCommentToPostOfUser(var user, var postIndex, var commentMessage) { var loadPostCB = { success: function(model, reponse, options) { var post = model.get("Posts")[postIndex]; addCommentToPost(post, commentMessage); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.statusCode); } } user.loadPosts(loadPostCB);}function test() { var me = apiomat.FBUser(); var saveUserCB = { success: function(model, response, options) { addCommentToPostOfUser(model, 0, "A comment"); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } me.save(saveUserCB);}FBUser me = new FBUser ();await me.SaveAsync ();//load list of postsme.LoadPostsAsync ();//create new commentFBComment comment = new FBComment();FBPost postWithComment = me.Posts[0];//set the post idcomment.PostId = postWithComment.Id;//add a message for your commentcomment.Message = "my comment";//now save the commentawait comment.SaveAsync();//also link togetherawait postWithComment.PostCommentsAsync(comment);
Certainly it’s possible to add a comment to posts of your friends.
If you don’t like your comment anymore you can easily delete it:
//do stuff like above//If you have the comment downloaded//than you can delete itcomment.delete();//do stuff like above//If you have the comment downloaded//than you can delete it[comment deleteAsyncWithBlock:^(NSError *error) {}];//do stuff like above//If you have the comment downloaded//than you can delete itvar deleteCB = { onOk : function() { console.log("deleted"); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } };comment.deleteModel(deleteCB);//do stuff like above//If you have the comment downloaded//than you can delete itvar destroyCommentCB = { success: function(model, reponse, options) { console.log("successfully deleted comment"); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); }}comment.destroy(destroyCommentCB);//do stuff like above//If you have the comment downloaded//than you can delete itawait comment.DeleteAsync();
Accessing likes of a post:
private void test() { final FBUser me = new FBUser(); me.saveAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { printLikesOfPost(me, 0); } } });}private void printLikesOfPost(final FBUser user, final int postIndex) { user.loadPostsAsync("", new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { FBPost post = user.getPosts().get(postIndex); printLikesOfPost(user, post); } } });}private void printLikesOfPost(final FBUser user, final FBPost post) { post.loadLikesAsync("", new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { // Load likes of first post List<fblike> likes = post.getLikes(); Log.d("MyActivity", "Count likes: " + likes.size()); // Print out the name of the persons which liked the post for (FBLike like : likes) { Log.d("MyActivity", like.getName()); } } } });}AOMFBUser *me = [[AOMFBUser alloc] init];[me saveAsyncWithBlock:^(NSError *error) { // download list of posts [me loadPostsAsync:@"" andWithBlock:^(NSError *error) { if(error == FALSE) { // Load likes of first post [[me posts][0] loadLikesAsync:@"" andWithBlock:^(NSError *error) { if(error == FALSE) { NSLog(@"Count likes: %i", [[[me posts][0] likes] count] ); // Print out the name of the persons which liked the post for (AOMFBLike like in [[me posts][0] likes]) { NSLog(@"%@", [like name]); } } else { NSLog(@ "Error occured: %@", [error userInfo]); } }]; } }];}];function test() { var me= new Apiomat.FBUser(); var saveCB = { onOk : function() { printLikesOfPost(me, 0); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; me.save(saveCB);}function printLikesOfPost(var user, var postIndex) { var loadPostsCB = { onOk : function() { var post = user.getPosts().get(postIndex); printLikesOfPost(user, post); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; user.loadPosts(loadPostsCB);}function printLikesOfPost(var user, var post) { var loadLikesCB = { onOk : function() { // Load likes of first post var likes = post.getLikes(); console.log("Count likes: " + likes.length); for (index = 0; index < comments.length; ++index) { console.log(comments[index]); } }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; post.loadLikes(loadLikesCB);}function printLikesOfPost(var post) { var loadLikesCB = { success: function(model, response, options) { var likes = post.get("Likes"); for (var i = 0; i likes.length; i++) { console.log(likes[i]); } }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.statusCode); } } post.loadLikes(loadLikesCB);}function printLikesOfPostOfUser(var user, var postIndex) { var loadPostsCB = { success: function(model, response, options) { var posts = model.get("Posts"); printLikesOfPost(posts[postIndex]); }, error: function (model, reponse, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.statusCode); } } user.loadPosts(loadPostsCB);}function test() { var me = apiomat.FBUser(); var saveUserCB = { success: function(model, response, options) { printLikesOfPostOfUser(model, 0); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } me.save(saveUserCB);}FBUser me = new FBUser ();await me.SaveAsync ();me.LoadPostsAsync ();if (me.Posts.Count > 0){ FBPost post = me.Posts [0]; Console.WriteLine ("content of first post: " + post.Message); await post.LoadLikesAsync(); IList<FBLike> likes = post.Likes; foreach (FBLike like in likes) { Console.WriteLine ("Like from: " + like.Name); }}
As of Nov 17, 2016 Facebook changed the behavior of publishing likes, this action is only possible with Page Access Tokens. As the SDKs are using a User Access Token, it is not possible to publish likes using any SDK. For documentation purposes, you can see the former code snippet below:
private void test() { final FBUser me = new FBUser(); me.saveAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { likePost(me, 0); } } });}private void likePost(final FBUser user, final int postIndex) { user.loadPostsAsync("", new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { FBPost post = user.getPosts().get(postIndex); likePost(post); } } });}private void likePost(final FBPost post) { // Create a new like final FBLike like = new FBLike(); // persist the like object first like.saveAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { likePost(post, like); } } });}private void likePost(final FBPost post, final FBLike like) { post.postLikesAsync(like, new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { // ... } } });}AOMFBLike *likeIt = [[AOMFBLike alloc] init];AOMFBUser *myUser = [[AOMFBUser alloc] init];[myUser saveAsyncWithBlock:^(NSError *error) { // persist the like object first [likeIt saveAsyncWithBlock:^(NSError *error) { // download list of posts [myUser loadPostsAsync:@"" andWithBlock:^(NSError *error) { if(error == FALSE) { NSMutableArray *posts = [me posts]; [posts[1] postLikesAsync:likeIt andWithBlock:^(NSError *error) { }]; } else { NSLog(@ "Error occured: %@", [error userInfo]); } }]; }];}];function test() { var me= new Apiomat.FBUser(); var saveCB = { onOk : function() { likePost(me, 0); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; me.save(saveCB);}function likePostLoad(var user, var postIndex) { var loadPostsCB = { onOk : function() { var post = user.getPosts().get(postIndex); likePostSave(post); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; user.loadPosts(loadPostsCB);}function likePostSave(var post) { var like= new Apiomat.FBLike(); var saveCB = { onOk : function() { var post = user.getPosts().get(postIndex); likePost(post); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; like.save(saveCB);}function likePost( var post, var like) { var postLikesCB = { onOk : function() { //console.log(); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; post.postLikes(postLikesCB);}function linkCommentToPost(like, post) { var postLikeToPostCB = { success: function(model, response, options) { console.log("successfully posted like to post"); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } post.postLike(like, postLikeToPostCB); }}function addLikeToPost(var post) { var like = apiomat.FBLike(); saveLikeCB = { success: function(model, response, options) { linkLikeToPost(like, post); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } } comment.save(saveLikeCB);}function addLikeToPostOfUser(var user, var postIndex) { var loadPostCB = { success: function(model, response, options) { var post = model.get("Posts")[postIndex]; addLikeToPost(post); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.statusCode); } } user.loadPosts(loadPostCB);}function test() { var me = apiomat.FBUser(); var saveUserCB = { success: function(model, response, options) { addLikeToPostOfUser(model, 0); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.statusCode); } me.save(saveUserCB);}FBUser me = new FBUser ();await me.SaveAsync ();//load list of postsme.LoadPostsAsync ();//create new likeFBLike like = new FBLike();FBPost postWithComment = me.Posts[0];//now save the likeawait like.SaveAsync();//also link togetherawait postWithComment.PostLikesAsync(like);
Delete own like is easy:
private void test() { final FBUser me = new FBUser(); me.saveAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { deleteLike(me, 0, 0); } } });}private void deleteLike(final FBUser user, final int postIndex, final int likeIndex) { user.loadPostsAsync("", new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { FBPost post = user.getPosts().get(postIndex); deleteLike(post, likeIndex); } } });}private void deleteLike(final FBPost post, final int likeIndex) { post.loadLikesAsync("", new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { FBLike like = post.getLikes().get(likeIndex); deleteLike(post, like); } } });}private void deleteLike( final FBPost post, final FBLike like) { post.removeLikesAsync(like, new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { // ... } } });}AOMFBUser *myUser = [[AOMFBUser alloc] init];[myUser saveAsyncWithBlock:^(NSError *error) { // download list of posts [myUser loadPostsAsync:@"" andWithBlock:^(NSError *error) { if(error == FALSE) { NSMutableArray *posts = [me posts]; AOMFBPost post = posts[1]; deleteLike(post); } }];}];void deleteLike(AOMFBPost *post){ // get likes of post [post loadLikesAsync:@"" andWithBlock:^(NSError *error) { // You can only delete your own like [post removeLikesAsync:[post likes][0] andWithBlock:^(NSError *error) { if(error) { NSLog(@ "Error occured: %@", [error userInfo]); } }]; }];}function test() { var me= new Apiomat.FBUser(); var saveCB = { onOk : function() { deleteLike(me, 0, 0); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; me.save(saveCB);}function deleteLike(var user, var postIndex, var likeIndex) { var loadPostsCB = { onOk : function() { var post = user.getPosts().get(postIndex); deleteLikePosts(post, likeIndex); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; user.loadPosts(loadPostsCB); }function deleteLikePosts(var post, var likeIndex) { var loadLikesCB = { onOk : function() { var like = post.getLikes().get(likeIndex); deleteLikePost(post, like); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; post.loadLikes(loadLikesCB);}function deleteLikePost(var post,var like) { var removeLikesCB = { onOk : function() { //console.log(); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; post.removeLikes(removeLikesCB);}function deleteLike(post, like) { var removeLikeFromPostCB = { success: function(model, response, options) { console.log("successfully removed like from post"); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } } post.removeLike(like, removeLikeFromPostCB);}function deleteLikeFromPost(var post, var likeIndex) { loadLikesCB = { success: function(model, response, options) { deleteLike(post, post.get("Likes")[likeIndex]); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } } post.loadLikes(loadLikesCB);}function deleteLike(var user, var postIndex, var likeIndex) { var loadPostCB = { success: function(model, reponse, options) { var post = user.get("Posts")[postIndex]; deleteLikeFromPost(post, likeIndex); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } } user.loadPosts(loadPostCB);}function test() { var me = apiomat.FBUser(); var saveUserCB = { success: function(model, response, options) { deleteLike(model, 0, 0); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } me.save(saveUserCB);}FBUser me = new FBUser ();await me.SaveAsync ();//load list of postsme.LoadPostsAsync ();FBPost post = me.Posts[0]; if(post != null){ await post.LoadLikesAsync (); FBLike likeToDelete = post.Likes [0]; if (likeToDelete != null) { await post.RemoveLikesAsync (likeToDelete); }}
Get information about you
Here is an example how you get information about you. Don’t forget to set the facebook scope (about_me) in the app setup on dashboard (see also information about App Setup)
final FBUser me = new FBUser();me.saveAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { //Now you have access to your information like the name Log.d("MyActivity", "Name: " + me.getName( )); } }});AOMFBUser *myUser = [[AOMFBUser alloc] init];// You have to save the model first[myUser saveAsyncWithBlock:^(NSError *error) { if(error == FALSE) { //Now you have access to your information //e.g. the name NSLog(@"Name: %@", [myUser name]); }}];var me= new Apiomat.FBUser();var saveCB = { onOk : function() { console.log(me.getName()); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); }};me.save(saveCB);var me = apiomat.FBUser();var saveUserCB = { success: function(model, response, options) { console.log(model.get("Name")); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); }}me.save(saveUserCB);FBUser me = new FBUser ();await me.SaveAsync ();//Now you have access to your information like the nameConsole.WriteLine("Name: " + me.Name);
Fetch information about friends and posts of friends
You can get information about your friends by loading the friend list on your FBUser. Don’t forget to set the permission ‘friends_about_me’ in the dashboard (see also information about App Setup).
If the friend has authorized the same app on Facebook, you can load the posts from him. These posts can then be loaded using "loadPosts".
private void test() { final FBUser me = new FBUser(); me.saveAsync(new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { printFriendInfo(me); } } });}private void printFriendInfo(final FBUser user) { user.loadFriendsAsync("", new AOMEmptyCallback() { @Override public void isDone(ApiomatRequestException exception) { if (exception != null) { List<fbuser> friends = me.getFriends(); for (FBUser friend : friends) { Log.d("MyActivity", "Facebook ID: " + friend.getForeignId( ) ); Log.d("MyActivity", "Name of friend: " + friend.getName( ) ); } } } });}AOMFBUser *me = [[AOMFBUser alloc] init];// You have to save the model first[me saveAsyncWithBlock:^(NSError *error) { // Now download the list of friends [me loadFriendsAsync:@"" andWithBlock:^(NSError *error) { if(error == FALSE) { NSMutableArray *friends = [me friends]; for (AOMFBUser *friend in friends) { NSLog(@"Facebook ID: %@", [friend getForeignId]); NSLog(@"Name of friend: %@", [friend name]); } } else { NSLog(@ "Error occured: %@", [error userInfo]); } }];}];function test() { var me= new Apiomat.FBUser(); var saveCB = { onOk : function() { printFriendInfo(me); }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; me.save(saveCB);}function printFriendInfo(var user) { var loadFriendsCB = { onOk : function() { var friends = user.getFriends(); for (index = 0; index < friends.length; ++index) { console.log(friends[index]); } }, onError : function(error) { console.log("Some error occured: (" + error.statusCode + ")" + error.message); } }; me.loadFriends(loadFriendsCB);}function printFriendInfo(var user) { var loadFriendsCB = { success: function(model, response, options) { var friends = user.get("Friends"); for(var i = 0; i < friends.length; i++) { console.log(friends[i]); } }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } } user.loadFriends(loadFriendsCB);}function test() { var me = apiomat.FBUser(); var saveUserCB = { success: function(model, response, options) { printFriendInfo(model); }, error: function(model, response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } me.save(saveUserCB);}FBUser me = new FBUser ();await me.SaveAsync ();await me.LoadFriendsAsync ();IList<FBUser> friends = me.Friends;foreach (FBUser friend in friends){ Console.WriteLine ("Facebook ID: " + friend.ForeignId); Console.WriteLine ("Facebook Name: " + friend.Name);}
User Signup and Login with Facebook
When you read about how our SDKs work, you know that you need a user to configure the Datastore, so that saving and loading objects work (because the related requests need to be authenticated with the user credentials). The same works for our REST API.
But when you want your users to be able to login with their existing Facebook credentials, you don’t want to ask for separate credentials to create an object of the ApiOmat user class or a subclass. That’s what our Facebook login mechanism is for. You supply the Facebook token of your user (obtained from the official Facebook SDK) and receive a tuple that contains an ApiOmat User object and a token map with the tokens you need to authenticate:
private void fbLogin(final String fbToken) { FBUser.getOrCreate(fbToken, new AOMCallback() { @Override public void isDone(UserTokenMapTuple userTokenMapTuple, ApiomatRequestException exception) { if (exception != null) { User user = userTokenMapTuple.getUser(); String sessionToken = userTokenMapTuple.getTokenMap().get("sessionToken"); user.setSessionToken(sessionToken); Datastore.configureWithSessionToken(user); } } });} - (void) FbLogin: (NSString*) fbToken{ AOMFBUser* me = [[AOMFBUser alloc] init]; [AOMDatastore configureWithUser:member]; AOMUserTokenContainerTuple* tuple = [me loginFacebookUser:FB_ACCESSTOKEN]; AOMUser* member = tuple.user; user.sessionToken = tuple.tokenContainer.sessionToken; [AOMDatastore configureWithSessionTokenFromUser:user];}function fbLogin(fbToken) { Apiomat.FBUser.getOrCreateUser(fbToken, { onOk: function(userTokenMap) { var user = userTokenMap.user; var tokenMap = userTokenMap.tokenMap; user.setSessionToken(tokenMap.sessionToken); Apiomat.Datastore.configureWithUserSessionToken(user); }, onError: function(error) { console.log("Some error occured. " + error.statusCode + " --> " + error.message); } )}function fBLogin(var fbToken) { var fBUser = apiomat.FBUser(); var fbLoginCB = { success: function(success, response) { if(success) { var tokenMap = response.tokenMap; apiomat.authenticationService().configureWithUserSessionToken(tokenMap.access_token); } }, error: function(model response, options) { console.log("some error occured: (" + options.error.statusCode + ") " + options.error.message); } } fbUser.loginFacebookUser(fbToken, fbLoginCB);}func FBLogin(fbToken: String) { let comp: CompletionHandlerWithUserTokenContainer = { data, error in if(error == nil) { DataStore.configureWithSessionToken(data.tokenContainer.sessionToken!) //now you can go on } else { //handle error } } let fbUser = FBUser(); fbuser.loginFacebookUser(fbToken, completion: comp)}private void FbLoginAsync(string fbToken){ Tuple<User, IDictionary> userTokenMapTuple = await FBUser.GetOrCreateUserAsync(fbToken).ConfigureAwait(false); User user = userTokenMapTuple.Item1; IDictionary tokenMap = userTokenMapTuple.Item2; user.SessionToken = tokenMap["SessionToken"]; Datastore.ConfigureWithSessionToken(user);}
The example code already configures the Datastore with the received session token. So from then on normal requests to the backend can be made, like myObj.saveAsync(); in Java.
This mechanism also works if your user signed up the conventional way before and now wants to login with Facebook. When the user object that already exists in the backend already has a Facebook ID attached and it’s the same as the one of the Facebook User with whose credentials your user just logs in, you also get the same return type with a user and a tokenMap. The existing user object also gets assigned some additional data if the attributes don’t have any values yet (first name, last name, date of birth).