Skip to main content
A Facebook permission is a grant from the user that allows your app to read or write a specific category of their data. You declare the permissions you need in LoginConfiguration, and the user approves or declines them in the Facebook login dialog.

Read vs. publish permissions

Facebook permissions fall into two broad categories: Read permissions let your app retrieve information about the user. Examples include public_profile, email, and user_friends. You can request read permissions any time during the login flow. Publish permissions let your app post content on the user’s behalf. Examples include publish_actions and pages_manage_posts. Facebook requires you to go through App Review before your app can use publish permissions for users other than yourself.
Facebook does not allow mixing read and publish permissions in a single login request. Create separate LoginConfiguration instances for each category.

The Permission type

The SDK represents permissions with the Permission enum, which is ExpressibleByStringLiteral. You can use either the enum case or the raw string:
// Using enum cases
let permissions: Set<Permission> = [.publicProfile, .email, .userFriends]

// Using string literals (converted automatically)
let permissions: Set<Permission> = ["public_profile", "email", "user_friends"]

// Custom permission (not built-in)
let custom: Permission = .custom("user_age_range")
Every Permission exposes a .name string that matches the raw Facebook permission name:
Permission.email.name       // "email"
Permission.userFriends.name // "user_friends"

Common permissions

PermissionEnum caseDescription
public_profile.publicProfileName, profile picture, and other public fields
email.emailPrimary email address
user_friends.userFriendsFriends who also use your app
user_birthday.userBirthdayDate of birth
user_location.userLocationCurrent city
user_photos.userPhotosPhotos uploaded or tagged
user_posts.userPostsPosts on the user’s timeline
user_gender.userGenderGender
user_age_range.userAgeRangeAge range
user_link.userLinkFacebook profile URL
user_hometown.userHometownHometown location
user_events.userEventsEvents the user hosts or RSVPs to
user_videos.userVideosVideos uploaded or tagged
user_likes.userLikesPages and objects the user has liked
pages_show_list.pagesShowListPages the user manages
ads_read.adsReadAds Insights API data

Request permissions in LoginConfiguration

Pass your permissions to LoginConfiguration. The SDK validates that permission strings contain no whitespace:
// Using the Swift convenience initializer with Permission values
guard let config = LoginConfiguration(
    permissions: [.publicProfile, .email],
    tracking: .enabled
) else {
    // Initialization fails if any permission string is invalid
    return
}

loginManager.logIn(viewController: self, configuration: config) { result in
    // ...
}
You can also pass raw strings, which is useful when working with permission names that are not built into the SDK:
guard let config = LoginConfiguration(
    permissions: ["public_profile", "email"],
    tracking: .enabled
) else { return }

Check granted and declined permissions in the result

The LoginResult.success case carries the permissions granted and declined in this specific request:
loginManager.logIn(viewController: self, configuration: config) { result in
    switch result {
    case let .success(granted, declined, token):
        if granted.contains(.email) {
            // Email permission was granted in this request
        }
        if declined.contains(.email) {
            // User explicitly declined email
            // Explain why email improves their experience
        }
    case .cancelled:
        break
    case let .failed(error):
        print(error)
    }
}
To check the complete set of permissions for the current session, read them from AccessToken.current:
if let token = AccessToken.current {
    let allGranted = token.permissions          // Set<Permission>
    let allDeclined = token.declinedPermissions  // Set<Permission>
    let allExpired = token.expiredPermissions    // Set<Permission>

    if token.hasGranted(.email) {
        print("Email permission is active")
    }
}

Check permissions before requesting them

Avoid requesting a permission the user has already granted. Check AccessToken.current first to minimize unnecessary dialogs:
func ensureEmailPermission() {
    if AccessToken.current?.hasGranted(.email) == true {
        // Already granted — no need to ask again
        return
    }

    guard let config = LoginConfiguration(
        permissions: [.email],
        tracking: .enabled
    ) else { return }

    loginManager.logIn(viewController: self, configuration: config) { result in
        // handle
    }
}

Best practices

Request the minimum set. Only request permissions when your app genuinely needs them for a specific feature. Requesting unnecessary permissions reduces conversion at the consent screen and may cause Facebook App Review to reject your app.
Explain before asking. Show a short explanation of why you need the permission before triggering the login dialog. Users are more likely to grant permissions when they understand the value.
Some permissions require your app to go through Facebook’s App Review process before they are available to users other than app admins and testers. Check the Facebook developer documentation for the review requirements of each permission.

Build docs developers (and LLMs) love