CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-facebook-android--facebook-android-sdk

Facebook SDK for Android providing comprehensive integration with Facebook platform features including Login, Sharing, Messenger, App Links, Analytics, and Graph API

Pending
Overview
Eval results
Files

graph-api.mddocs/

Graph API

The Facebook Graph API module provides direct access to Facebook's Graph API for reading and writing Facebook data. It offers request building, batch operations, response handling, and comprehensive error management.

Graph Request

The GraphRequest class is the primary interface for making Graph API calls.

class GraphRequest private constructor() {
    val accessToken: AccessToken?
    val graphPath: String?
    val httpMethod: HttpMethod
    val parameters: Bundle?
    val graphObject: JSONObject?
    val tag: Any?
    val version: String?
    val skippedResultKeys: Set<String>?
    val callback: Callback?
    
    companion object {
        // Me requests
        fun newMeRequest(
            accessToken: AccessToken?,
            callback: GraphJSONObjectCallback?
        ): GraphRequest
        
        fun newMyFriendsRequest(
            accessToken: AccessToken?,
            callback: GraphJSONArrayCallback?
        ): GraphRequest
        
        // Generic requests
        fun newGraphPathRequest(
            accessToken: AccessToken?,
            graphPath: String?,
            callback: Callback?
        ): GraphRequest
        
        // Post requests
        fun newPostRequest(
            accessToken: AccessToken?,
            graphPath: String?,
            graphObject: JSONObject?,
            callback: Callback?
        ): GraphRequest
        
        // Delete requests  
        fun newDeleteObjectRequest(
            accessToken: AccessToken?,
            objectId: String?,
            callback: Callback?
        ): GraphRequest
        
        // Places search
        fun newPlacesSearchRequest(
            accessToken: AccessToken?,
            location: Location,
            radiusInMeters: Int,
            resultsLimit: Int,
            searchText: String?,
            callback: GraphJSONArrayCallback?
        ): GraphRequest
        
        // Custom audience
        fun newCustomAudienceThirdPartyIdRequest(
            accessToken: AccessToken?,
            context: Context,
            callback: Callback?
        ): GraphRequest
    }
    
    // Execution
    fun executeAsync(): GraphRequestAsyncTask
    fun executeAndWait(): GraphResponse
    
    // Configuration
    fun setParameters(parameters: Bundle?)
    fun setGraphObject(graphObject: JSONObject?)
    fun setTag(tag: Any?)
    fun setVersion(version: String?)
    fun setSkippedResultKeys(skippedResultKeys: Collection<String>?)
    fun setCallback(callback: Callback?)
    
    // Callbacks
    interface Callback {
        fun onCompleted(response: GraphResponse)
    }
    
    interface GraphJSONObjectCallback {
        fun onCompleted(jsonObject: JSONObject?, response: GraphResponse)
    }
    
    interface GraphJSONArrayCallback {
        fun onCompleted(jsonArray: JSONArray?, response: GraphResponse)
    }
    
    interface OnProgressCallback {
        fun onProgress(current: Long, max: Long)
    }
}

enum class HttpMethod {
    GET, POST, DELETE
}

Basic Graph API Usage

// Get current user information
val request = GraphRequest.newMeRequest(
    AccessToken.getCurrentAccessToken()
) { jsonObject, response ->
    if (response.error == null) {
        val userId = jsonObject?.getString("id")
        val name = jsonObject?.getString("name")
        val email = jsonObject?.getString("email")
        
        Log.d("GraphAPI", "User: $name ($userId), Email: $email")
    } else {
        Log.e("GraphAPI", "Error: ${response.error?.errorMessage}")
    }
}

// Request specific fields
val parameters = Bundle()
parameters.putString("fields", "id,name,email,picture.type(large)")
request.parameters = parameters

// Execute the request
request.executeAsync()

Custom Graph API Requests

// Make a custom GET request
val request = GraphRequest.newGraphPathRequest(
    AccessToken.getCurrentAccessToken(),
    "/me/posts"
) { response ->
    if (response.error == null) {
        val jsonObject = response.jsonObject
        val postsArray = jsonObject?.optJSONArray("data")
        // Process posts
    }
}

// Add parameters for pagination and fields
val parameters = Bundle()
parameters.putString("fields", "id,message,created_time,likes.summary(true)")
parameters.putInt("limit", 25)
request.parameters = parameters
request.executeAsync()

// Make a POST request
val postData = JSONObject()
postData.put("message", "Hello from my app!")
postData.put("link", "https://example.com")

val postRequest = GraphRequest.newPostRequest(
    AccessToken.getCurrentAccessToken(),
    "/me/feed",
    postData
) { response ->
    if (response.error == null) {
        val postId = response.jsonObject?.getString("id")
        Log.d("GraphAPI", "Post created with ID: $postId")
    }
}
postRequest.executeAsync()

Graph Response

class GraphResponse(
    request: GraphRequest,
    connection: HttpURLConnection?,
    error: FacebookRequestError?
) {
    val request: GraphRequest
    val rawResponse: String?
    val jsonObject: JSONObject?
    val jsonArray: JSONArray?
    val error: FacebookRequestError?
    val connection: HttpURLConnection?
    
    companion object {
        fun createResponsesFromString(
            responseString: String,
            requests: List<GraphRequest>
        ): List<GraphResponse>
        
        fun fromHttpConnection(
            connection: HttpURLConnection,
            requests: List<GraphRequest>
        ): List<GraphResponse>
    }
}

Batch Requests

Execute multiple Graph API requests in a single HTTP call:

class GraphRequestBatch : AbstractList<GraphRequest> {
    constructor()
    constructor(requests: Collection<GraphRequest>)
    constructor(vararg requests: GraphRequest)
    
    val requests: List<GraphRequest>
    val timeout: Int
    val callbackHandler: Handler?
    val batchApplicationId: String?
    
    fun setTimeout(timeoutInMilliseconds: Int)
    fun addCallback(callback: Callback)
    fun removeCallback(callback: Callback)
    
    // Execution
    fun executeAsync(): GraphRequestAsyncTask
    fun executeAndWait(): List<GraphResponse>
    
    interface Callback {
        fun onBatchCompleted(batch: GraphRequestBatch)
    }
    
    interface OnProgressCallback {
        fun onBatchProgress(batch: GraphRequestBatch, current: Long, max: Long)
    }
}

Batch Request Usage

// Create multiple requests
val meRequest = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken()) { obj, response ->
    // Handle user info
}

val friendsRequest = GraphRequest.newMyFriendsRequest(AccessToken.getCurrentAccessToken()) { array, response ->
    // Handle friends list
}

val postsRequest = GraphRequest.newGraphPathRequest(
    AccessToken.getCurrentAccessToken(),
    "/me/posts"
) { response ->
    // Handle posts
}

// Create batch and execute
val batch = GraphRequestBatch(meRequest, friendsRequest, postsRequest)
batch.addCallback { batch ->
    Log.d("GraphAPI", "Batch completed with ${batch.size} requests")
}
batch.executeAsync()

Async Task Management

class GraphRequestAsyncTask : AsyncTask<Void, Void, List<GraphResponse>> {
    constructor(connection: HttpURLConnection, vararg requests: GraphRequest)
    constructor(requests: Collection<GraphRequest>)
    constructor(batch: GraphRequestBatch)
    
    val requests: List<GraphRequest>
    val exception: Exception?
    
    override fun toString(): String
}

Error Handling

class FacebookRequestError(
    requestStatusCode: Int,
    errorCode: Int,
    errorType: String?,
    errorMessage: String?
) {
    val requestStatusCode: Int
    val errorCode: Int
    val errorType: String?
    val errorMessage: String?
    val errorUserMessage: String?
    val errorUserTitle: String?
    val requestResult: JSONObject?
    val batchRequestResult: JSONObject?
    val exception: FacebookException?
    
    val category: Category
    
    enum class Category {
        LOGIN_RECOVERABLE,  // User can fix by logging in again
        OTHER,              // Non-recoverable error
        TRANSIENT          // Temporary error, retry may work
    }
    
    companion object {
        const val INVALID_ERROR_CODE = -1
        const val INVALID_HTTP_STATUS_CODE = -1
    }
}

class FacebookGraphResponseException(
    response: GraphResponse,
    message: String?
) : FacebookException(message) {
    val graphResponse: GraphResponse
}

Error Handling Example

val request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken()) { jsonObject, response ->
    val error = response.error
    if (error != null) {
        when (error.category) {
            FacebookRequestError.Category.LOGIN_RECOVERABLE -> {
                // Token expired or invalid, prompt user to login again
                Log.w("GraphAPI", "Login required: ${error.errorMessage}")
                AccessToken.setCurrentAccessToken(null)
                redirectToLogin()
            }
            FacebookRequestError.Category.TRANSIENT -> {
                // Temporary error, retry after delay
                Log.w("GraphAPI", "Transient error: ${error.errorMessage}")
                Handler().postDelayed({ request.executeAsync() }, 5000)
            }
            FacebookRequestError.Category.OTHER -> {
                // Permanent error
                Log.e("GraphAPI", "API error: ${error.errorMessage}")
                showErrorToUser(error.errorUserMessage ?: error.errorMessage)
            }
        }
    } else {
        // Success - process the response
        processUserData(jsonObject)
    }
}

Pagination

Handle paginated Graph API responses:

fun loadUserPosts(after: String? = null) {
    val request = GraphRequest.newGraphPathRequest(
        AccessToken.getCurrentAccessToken(),
        "/me/posts"
    ) { response ->
        if (response.error == null) {
            val jsonObject = response.jsonObject
            val data = jsonObject?.optJSONArray("data")
            
            // Process current page of posts
            processPosts(data)
            
            // Check for next page
            val paging = jsonObject?.optJSONObject("paging")
            val nextPageUrl = paging?.optString("next")
            val cursors = paging?.optJSONObject("cursors")
            val afterCursor = cursors?.optString("after")
            
            if (!nextPageUrl.isNullOrEmpty()) {
                // Load next page
                loadUserPosts(afterCursor)
            }
        }
    }
    
    // Set parameters including pagination cursor
    val parameters = Bundle()
    parameters.putString("fields", "id,message,created_time")
    parameters.putInt("limit", 25)
    if (after != null) {
        parameters.putString("after", after)
    }
    request.parameters = parameters
    request.executeAsync()
}

File Uploads

Upload files through the Graph API:

fun uploadPhoto(bitmap: Bitmap, message: String) {
    val request = GraphRequest.newUploadPhotoRequest(
        AccessToken.getCurrentAccessToken(),
        "/me/photos",
        bitmap,
        message
    ) { response ->
        if (response.error == null) {
            val photoId = response.jsonObject?.getString("id")
            Log.d("GraphAPI", "Photo uploaded with ID: $photoId")
        } else {
            Log.e("GraphAPI", "Upload failed: ${response.error?.errorMessage}")
        }
    }
    request.executeAsync()
}

fun uploadVideo(videoUri: Uri, title: String) {
    val request = GraphRequest.newUploadVideoRequest(
        AccessToken.getCurrentAccessToken(),
        "/me/videos",
        videoUri,
        title
    ) { response ->
        if (response.error == null) {
            val videoId = response.jsonObject?.getString("id")
            Log.d("GraphAPI", "Video uploaded with ID: $videoId")
        }
    }
    request.executeAsync()
}

Graph API Versioning

// Use specific API version
val request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken()) { obj, response ->
    // Handle response
}
request.version = "v18.0"
request.executeAsync()

// Set default version for all requests
FacebookSdk.setGraphApiVersion("v18.0")

Install with Tessl CLI

npx tessl i tessl/maven-com-facebook-android--facebook-android-sdk

docs

app-events.md

app-links.md

bolts-tasks.md

core-authentication.md

gaming.md

graph-api.md

index.md

login.md

messenger.md

sharing.md

tile.json