React Native SDK
SDKs and APIs
The Kinde React Native SDK allows developers to quickly and securely integrate a new or an existing React Native application into the Kinde platform. This SDK is for people using Expo.
If you haven’t already got a Kinde account, register for free here (no credit card required). Registering gives you a Kinde domain, which you need to get started, e.g. yourapp.kinde.com.
You will need Node, the React Native command line interface, a JDK, Android Studio (for Android) and Xcode (for iOS).
Follow the installation instructions for your chosen OS to install dependencies.
npm i @kinde/expoyarn add @kinde/expopnpm add @kinde/expo<KindeAuthProvider config={{ domain: "<KINDE DOMAIN>", // e.g https://mybusiness.kinde.com clientId: "<CLIENT ID>", }} // All callbacks are optional callbacks={{ onSuccess: async (token, state, context) => { }, onError: (error) => { }, onEvent: async (event, state, context) => { }, }}> {/* Your app components go here */}</KindeAuthProvider>const kinde = useKindeAuth();
const handleSignUp = async () => { const token = await kinde.register();
if (token) { // User was authenticated }};
const handleSignIn = async () => { const token = await kinde.login(); if (token) { // User was authenticated }};
const handleLogout = async () => { console.log("logout", await kinde.logout());};<Pressable onPress={handleSignIn}> <ThemedText>Sign In</ThemedText></Pressable>Login and register methods accept and object containing all Kinde supported URL parameters.
Logout accepts object which allows you to revoke the token
kinde.logout({ revokeToken: true })useKindeAuth)isAuthenticated - Returns true/false if the user is authenticated<myapp://localhost:3000><myapp://localhost:3000>Make sure you press the Save button at the bottom of the page!
Note: The <myapp://localhost:3000> is used as an example of local URL Scheme, change to the local URL Scheme or production URL Scheme that you use.
A selection of utility functions are available.
Expo 53+: Import from @kinde/expo/utils and useKindeAuth hook
Expo 51 and 52: Import from @kinde/js-utils and useKindeAuth hook
import { getUserProfile, getFlag, getRoles } from "@kinde/expo/utils";
// Example usageconst checkUserProfile = async () => { const profile = await getUserProfile(); console.log("User profile:", profile);};getDecodedToken - Get token decoded valuesgetUserProfile - Get the current user’s profilegetFlag - Check feature flag valuesgetRoles - Get the current user’s rolesgetCurrentOrganization - Get the current organizationgetUserOrganizations - Get all organizations the user belongs togetPermission - get a single permission valuegetPermissions - get all user permissionsgetClaim - Get a specific claim from the tokengetClaims - Get all claims from the tokenrefreshToken - Manually refresh the access tokengetDecodedTokenGet the decoded access token or ID token.
getDecodedToken = async <T = JWTDecoded>( tokenType: "accessToken" | "idToken" = StorageKeys.accessToken,): Promise<(T & JWTDecoded) | null>Example usage:
// Get the decoded access tokenconst decodedAccessToken = await getDecodedToken("accessToken");// Get the decoded ID tokenconst decodedIdToken = await getDecodedToken("idToken");
// Adding custom claims to the decoded tokenconst decodedAccessTokenWithCustomClaims = await getDecodedToken<{ customClaim: string;}>("accessToken");getClaimGets a claim from an access or ID token.
getClaim = async <T = JWTDecoded, V = string | number | string[]>( keyName: keyof T, tokenType: "accessToken" | "idToken" = "accessToken",): Promise<{ name: keyof T; value: V;} | null>Example usage:
// Get the decoded access tokenconst roles = await getClaim("roles", "accessToken");// Get the decoded ID tokenconst givenName = await getClaim("given_name", "idToken");
// Acessing custom claimsconst decodedAccessTokenWithCustomClaims = await getClaim<{ customClaim: string;}>("customClaim", "accessToken");getCurrentOrganizationReturns the current users logged in organization code.
getCurrentOrganization = async (): Promise<string | null>Example usage:
// Get the decoded access tokenconst orgCode = await getCurrentOrganization();// org_123456getUserOrganizationsReturns all organization codes the current user belongs to.
getUserOrganizations = async (): Promise<string[] | null>Example usage:
// Get the decoded access tokenconst orgCode = await getUserOrganizations();// [// "org_0000000000001",// "org_0000000000002",// "org_0000000000003",// "org_0000000000004// ]getFlagGet the value of a feature flag.
getFlag = async <T = string | boolean | number | object>( name: string,): Promise<T | null>Example usage:
// Get the feature flag valueconst featureValue = await getFlag("feature_flag_name");
// Define the type of the feature flagconst featureValue = await getFlag<string>("feature_flag_name");const featureValue = await getFlag<boolean>("feature_flag_name");const featureValue = await getFlag<number>("feature_flag_name");const featureValue = await getFlag<object>("feature_flag_name");getPermissionGet the value of a feature flag.
getPermission = async <T = string>( permissionKey: T,): Promise<PermissionAccess>Example usage:
// Get the feature flag valueconst permission = await getPermission("feature_flag_name");// {// permissionKey: "feature_flag_name",// orgCode: "org_123456",// isGranted: true / false,// }getPermissionsGet the permissions for the current user for the organization they are signed into.
getPermissions = async <T = string>( permissionKey: T,): Promise<PermissionAccess>Example usage:
// Get the feature flag valueconst permissions = await getPermissions("feature_flag_name");// {// orgCode: "org_123456",// permissions: [// "create:todos",// "update:todos",// "read:todos",// "delete:todos",// "create:tasks",// "update:tasks",// "read:tasks",// "delete:tasks// ]// }getRolesGet the users Roles
Note: Roles are optional in the token, will need to add to the token in your application settings
getRoles = async (): Promise<Role[]>Example usage:
// Get the feature flag valueconst roles = await getRoles();// [// {// id: "01932730-c828-c01c-9f5d-c8f15be13e24",// key: "admin",// name: "admin",// },// ]getUserProfilegetUserProfile = async <T>(): Promise< (UserProfile & T) | null>Example usage:
// Get the feature flag valueconst roles = await getUserProfile();// {// "email": "someuser@emaildomain.com",// "familyName": "Bloggs",// "givenName": "Joe",// "id": "kp_1234...",// "picture": "https://example.com/image.png",// }refreshTokenrefreshToken = async ({ domain, clientId, refreshType = RefreshType.refreshToken, onRefresh,}: { domain: string; clientId: string; refreshType?: RefreshType; onRefresh?: (data: RefreshTokenResult) => void;}): Promise<RefreshTokenResult>Example usage:
const refreshToken = await refreshToken({ domain: "https://mybusiness.kinde.com", clientId: "client_id"});// {// accessToken: "eyJhbGciOiJSUzI1N...",// idToken: "eyJhbGciOiJSUzI1N...",// refreshToken: "E5hxe-AOSTcFjri3YV...",// success: true,// }Sometimes there will be issues related to caching when you develop React Native. There are some recommendations for cleaning the cache:
node_modules, yarn.lock or package-lock.json.yarn cache clean or npm cache clean --force..env file.yarn install or npm install.yarn start --reset-cache or npm start --reset-cache.Assume your StarterKit path is <StarterKit_PATH>.
Clean cache for Android
Run this:
cd <StarterKit_PATH>/android./gradlew cleanClean cache for iOS
Run this:
cd <StarterKit_PATH>/iosrm -rf Pods && rm Podfile.lockClean build folders on Xcode.
If you need help connecting to Kinde, please contact us at support@kinde.com.