A common question we get from developers is how to keep information of Users or Pages using their apps up to date. We wanted to share some of the best practices that can improve the reliability and performance of apps you write on Facebook.
We often see developers querying the Graph API each time a User logs in to their apps to fetch information and update their records. This presents several issues and has a huge hit on performance.
Instead, we encourage you to use the Real-time Updates API that we designed especially for this purpose, allowing developers to subscribe to changes in data in Facebook. Rather than polling Facebook’s servers, your app can then cache data and receive updates whenever the data changes.
For example, many apps rely on a User's location to fetch and display relevant information, it is very important that this data stays up to date on the app’s backend.
Real-time updates allows you to set up a subscription on the location
field of the User object, whenever that field changes, Facebook will make an HTTP POST request to a callback URL you specified by with a list of changes.
You can currently subscribe to updates for these types of objects:
Below is PHP Sample code that sets up an endpoint that will receive both GET (for subscription verification) and POST requests (for actual change data).
<?php $verify_token = 'YOURVERIFYTOKEN'; if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_GET['hub_mode']) && $_GET['hub_mode'] == 'subscribe' && isset($_GET['hub_verify_token']) && $_GET['hub_verify_token'] == $verify_token) { echo $_GET['hub_challenge']; } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { $post_body = file_get_contents('php://input'); $obj = json_decode($post_body, true); // $obj will contain the list of fields that have changed } ?>
Once this endpoint is set up, you will need to make a POST request to the actual Real-Time updates API to subscribe to a field.
<?php $app_id = 'YOUR_APP_ID'; $app_secret = 'YOUR_APP_SECRET'; $app_url = 'http://YOURAPPURL'; $fields = 'location'; $verify_token = 'YOURVERIFYTOKEN'; // Fetching an App Token $app_token_url = 'https://graph.facebook.com/oauth/access_token?client_id=' .$app_id.'&client_secret='.$app_secret .'&grant_type=client_credentials'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $app_token_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $res = curl_exec($ch); parse_str($res, $token); if (isset($token['access_token'])) { // Let's register a callback $params = array( 'object' => 'user', 'fields' => $fields, 'callback_url' // This is the endpoint that will be called when // a User updates the location field => $app_url . '/index.php?action=callback', 'verify_token' => $verify_token, ); curl_setopt($ch, CURLOPT_URL, 'https://graph.facebook.com/' .$app_id.'/subscriptions?access_token=' .$token['access_token']); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); $res = curl_exec($ch); if ($res && $res != 'null') { print_r($res); } // Fetch list of all callbacks curl_setopt($ch, CURLOPT_POST, 0); $res = curl_exec($ch); } if ($res && $res != 'null') { print_r($res); } curl_close($ch); ?>
The code above should return a similar object listing current subscriptions:
{ "data":[ { "object":"user", "callback_url":"http:\/\/YOURAPPURL\/index.php?action=callback", "fields":[ "location" ], "active":true } ] }
It’s important to note that for security reasons, the POST request made by Facebook’s servers to your endpoint will never actually contain the data that changed but only the field.
This is what a query from Facebook's servers to your endpoint may look like:
{ "object":"user", "entry":[ { "uid":"499535393", "id":"499535393", "time":1326210816, "changed_fields":[ "location" ] } ] }
Once your endpoint gets called you can either query the Graph API immediately to fetch the new information or schedule it for a later call (next user login for example).
You can find more information about the Real-Time Updates API here.