Skip to content

Latest commit

 

History

History
1388 lines (989 loc) · 34.8 KB

File metadata and controls

1388 lines (989 loc) · 34.8 KB
page_id f626b8e4-79c2-4d17-8148-b298c115a552
title React Native SDK
description Comprehensive guide for React Native SDK including Android/iOS setup, native linking, Expo compatibility, and mobile authentication integration.
sidebar
order
19
relatedArticles
3e372a8b-9168-4d50-a5e7-13941cfbd632
head
topics
developer-tools
sdks
react-native
native
sdk
react-native
languages
javascript
jsx
typescript
java
kotlin
swift
audience
developers
complexity advanced
keywords
react native sdk
mobile authentication
android setup
ios setup
expo compatibility
native linking
cocoapods
updated 2026-04-14
featured false
deprecated false
ai_summary Comprehensive guide for React Native SDK including Android/iOS setup, native linking, Expo compatibility, and mobile authentication integration.

The Kinde React Native SDK allows developers to quickly and securely integrate a new or an existing React Native application into the Kinde platform.

Supported versions

React Native SDK 0.6x

Kinde React Native SDK 0.6x is compatible with React Native versions 0.60 to 0.69.

React Native SDK 0.7x

Kinde React Native SDK 0.7x is compatible with React Native versions 0.70 or higher.

Expo

Kinde React Native SDK 0.6x and Kinde React Native SDK 0.7x are designed to work well with Expo. You can easily incorporate them into your Expo projects by following the instructions provided in the Expo and React Native SDK documentation.

Compatible versions:

You can also check out our starter kits on GitHub:

Before you begin

  • 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 also 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.

Fundamentally, both SDK versions have equivalent functionality, so there should be no issue integrating either of them. In this guide, we use examples from version 0.7x. But version 0.6x is identical in terms of integration and application.

Installation

Required dependencies

The SDK requires the react-native-app-auth, react-native-keychain and react-native-get-random-values packages to be installed.

Because the Kinde SDK requires React Native 0.60 or higher, native dependencies are automatically linked. You do not need to run react-native link or manually add libraries to your Xcode workspace or Android build files.

iOS

Before installing CocoaPods, ensure you have Ruby and Bundler set up correctly on your system.

Shell setup

# Install or update Bundler
gem install bundler

# Create a new Gemfile if it doesn't exist
bundle init

# Add CocoaPods to your Gemfile
bundle add cocoapods

# Install dependencies using Bundler
bundle install

# Install pods for your project
cd ios && bundle exec pod install

Update iOS native dependencies

To update iOS native dependencies, you can use CocoaPods. We recommend installing CocoaPods using Homebrew.

brew install cocoapods

cd ios && pod install

If you encounter any errors during the SDK installation process, you can refer to the General Tips section at the end of this topic.

Kinde configuration

  1. In Kinde, go to Settings > Applications.
  2. Select View details on the Front-end app.
  3. Scroll down to the Callback URLs section.
  4. Add in the callback URLs for your React Native app, which should look something like this:
    • Allowed callback URLs - myapp://myhost.kinde.com/kinde_callback
    • Allowed logout redirect URLs - myapp://myhost.kinde.com/kinde_callback

Make sure you press the Save button at the bottom of the page!

Note: The myapp://myhost.kinde.com/kinde_callback is used as an example of local URL Scheme, change to the local local URL Scheme that you use.

Environments

If you would like to use our Environments feature as part of your development process. You will need to create them first within your Kinde account. In this case you would use the Environment subdomain in the code block above.

Configure your app

Environment variables

Put these variables in your .env file. You can find these variables on the same page as where you set the callback URLs.

  • KINDE_ISSUER_URL - your Kinde domain
  • KINDE_POST_CALLBACK_URL - After the user authenticates we will callback to this address. Make sure this URL is under your allowed callback URLs
  • KINDE_POST_LOGOUT_REDIRECT_URL - where you want users to be redirected to after logging out. Make sure this URL is under your allowed logout redirect URLs
  • KINDE_CLIENT_ID - you can find this on the App Keys page
KINDE_ISSUER_URL=https://your_kinde_domain.kinde.com
KINDE_POST_CALLBACK_URL=myapp://your_kinde_domain.kinde.com/kinde_callback
KINDE_POST_LOGOUT_REDIRECT_URL=myapp://your_kinde_domain.kinde.com/kinde_callback
KINDE_CLIENT_ID=your_kinde_client_id

Configuration example:

KINDE_ISSUER_URL=https://myhost.kinde.com
KINDE_POST_CALLBACK_URL=myapp://myhost.kinde.com/kinde_callback
KINDE_POST_LOGOUT_REDIRECT_URL=myapp://myhost.kinde.com/kinde_callback
KINDE_CLIENT_ID=myclient@live

Configure deep linking

Android

Open AndroidManifest.xml and update your scheme by adding a new block in activity.

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="myapp" android:host="your_kinde_host" />  // Please modify sheme and host to reflect your preferences.
</intent-filter>

iOS

Follow the instructions for the language your AppDelegate is written in.

  1. Create a new file, AppDelegate+RNAppAuth.h, in the same folder as your AppDelegate.swift and add the following code:

    #import "RNAppAuthAuthorizationFlowManager.h"
  2. Configure the Objective-C Bridging Header.

    How you do this depends on whether your project already has an Objective-C Bridging Header set.

    Check your Xcode Build Settings for Objective-C Bridging Header to see if a path is already set.

    Open for steps
    • Open the project in Xcode.
    • Select the project in the navigator, then the app target.
    • Open the Build Settings tab.
    • Search for Bridging Header.
    • Check the value next to the setting name.
      • If it is empty, you do not have an existing header.
      • If there is a file path, you already have one configured.
    Set `Objective-C Bridging Header` to the path of the newly created file: `$(SRCROOT)/$(TARGET_NAME)/AppDelegate+RNAppAuth.h`. Open the `Objective-C Bridging Header` file your project is already using (e.g., `YourApp-Bridging-Header.h`) and add the following import statement to it:
     ```diff lang="objc" title="YourApp-Bridging-Header.h"
     + #import "AppDelegate+RNAppAuth.h"
     ```
    

  3. Update AppDelegate.swift file with the following code:

    @main
    - class AppDelegate: UIResponder, UIApplicationDelegate {
    + class AppDelegate: UIResponder, UIApplicationDelegate, RNAppAuthAuthorizationFlowManager {
    +  
    +   public weak var authorizationFlowManagerDelegate: RNAppAuthAuthorizationFlowManagerDelegate?

    Custom scheme support:

    + func application(
    +   _ app: UIApplication,
    +   open url: URL,
    +   options: [UIApplication.OpenURLOptionsKey: Any] = [:]
    + ) -> Bool {
    +   if let authorizationFlowManagerDelegate = self.authorizationFlowManagerDelegate {
    +     if authorizationFlowManagerDelegate.resumeExternalUserAgentFlow(with: url) {
    +       return true
    +     }
    +   }
    +   return RCTLinkingManager.application(app, open: url, options: options)
    + }

    Universal link support:

    + func application(
    +   _ application: UIApplication,
    +   continue userActivity: NSUserActivity,
    +   restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
    + ) -> Bool {
    +   if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
    +     let url = userActivity.webpageURL,
    +     let delegate = authorizationFlowManagerDelegate,
    +     delegate.resumeExternalUserAgentFlow(with: url)
    +   {
    +     return true
    +   }
    +   return RCTLinkingManager.application(
    +     application,
    +     continue: userActivity,
    +     restorationHandler: restorationHandler
    +   )
    + }
1. Update your ``AppDelegate.h`` file to include the following:
    ```diff lang="objc" title="AppDelegate.h"
    + #import "RNAppAuthAuthorizationFlowManager.h"
    
    - @interface AppDelegate : RCTAppDelegate
    + @interface AppDelegate : RCTAppDelegate <RNAppAuthAuthorizationFlowManager>
    +
    + @property(nonatomic, weak) id<RNAppAuthAuthorizationFlowManagerDelegate> authorizationFlowManagerDelegate;
    ```

2. Update your ``AppDelegate.m`` (or ``AppDelegate.mm``) file to include the following:

    **Add the Linking Manager import to the top of the file:**
    
    ```diff lang="objc" title="AppDelegate.m"
    + #import <React/RCTLinkingManager.h>
    ```

    **Custom scheme support:**

    ```diff lang="objc" title="AppDelegate.m"
    + - (BOOL) application: (UIApplication *)application
    +              openURL: (NSURL *)url
    +              options: (NSDictionary<UIApplicationOpenURLOptionsKey, id> *) options
    + {
    +   if ([self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:url]) {
    +     return YES;
    +   }
    +   return [RCTLinkingManager application:application openURL:url options:options];
    + }
    ```

    **Universal link support:**

    ```diff lang="objc" title="AppDelegate.m"
    + - (BOOL) application: (UIApplication *) application
    + continueUserActivity: (nonnull NSUserActivity *)userActivity
    +   restorationHandler: (nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
    + {
    +   if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
    +     if (self.authorizationFlowManagerDelegate) {
    +       BOOL resumableAuth = [self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:userActivity.webpageURL];
    +       if (resumableAuth) {
    +         return YES;
    +       }
    +     }
    +   }
    +   return [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
    + }
    ```

Integrate with your app

To create a new instance of the KindeSDK object, execute the code below.

import { KindeSDK } from '@kinde-oss/react-native-sdk-0-7x';
...

...
const client = new KindeSDK(YOUR_KINDE_ISSUER, YOUR_KINDE_REDIRECT_URI, YOUR_KINDE_CLIENT_ID, YOUR_KINDE_LOGOUT_REDIRECT_URI);

KindeProvider (React Native 0.7x only)

The KindeProvider is a powerful component introduced in React Native SDK 0.7x that simplifies session management and SDK initialization. It handles the complexity of user session lifecycles on mobile devices, including token validation and refresh logic.

To use the KindeProvider, import it from the SDK:

import { useKindeProvider } from '@kinde-oss/react-native-sdk-0-7x';

The useKindeProvider hook initializes the SDK if it hasn't been initialized and returns a cached instance if it has. It also provides session state information and a reference to the SDK client.

Here's how to use it:

const { isAuthenticated, verifyToken, authSdk } = useKindeProvider({
  issuerUrl: 'https://myhost.kinde.com',
  redirectUri: 'myapp://myhost.kinde.com/kinde_callback',
  clientId: 'secret',
  logoutRedirectUri: 'myapp://myhost.kinde.com/kinde_callback',
});

The hook returns:

  • isAuthenticated: A boolean indicating the current authentication state
  • verifyToken: A function to verify the token's validity
  • authSdk: A reference to the initialized KindeSDK instance

This approach simplifies session management by:

  • Automatically handling SDK initialization
  • Caching the SDK instance appropriately
  • Managing token validation and refresh logic
  • Providing easy access to authentication state

Sign in and registration

Kinde provides methods for easily implementing a login / register flow. You can add buttons as follows.

<View>
    <View>
        <Button title="Sign In" onPress={handleSignIn} />
    </View>
    <View>
        <Button title="Sign Up" color="#000" onPress={handleSignUp} />
    </View>
</View>

Then define new functions that match for each button.

Note: Before proceeding, make sure you've defined the KindeSDK as a client variable.

...
const handleSignUp = async () => {
  const token = await client.register();
  if (token) {
    // User was authenticated
  }
};

const handleSignIn = async () => {
  const token = await client.login();
  if (token) {
    // User was authenticated
  }
};
...

Log out

This is implemented in much the same way as signing in or registering. The Kinde SPA client comes with a logout method:

const handleLogout = async () => {
  const loggedOut = await client.logout();
  if (loggedOut) {
    // User was logged out
  }
};

We have also implemented an API for token revocation. Pass true as an argument in the logout function. This flag will assist in revoking the token without having to open the website within your apps.

const handleLogout = async () => {
  const loggedOut = await client.logout(true);
  if (loggedOut) {
    // User was logged out
  }
};

Note: Handle redirects are now deprecated

Starting from version 1.1 of the SDK, the need to handle redirects has been eliminated. Authentication is now performed by launching a web browser within your app instead of relying on an external browser. For a comprehensive example of how to handle authentication, see below.

Full code sample for authentication

const checkAuthenticate = async () => {
  // Using `isAuthenticated` to check if the user is authenticated or not
  if (await client.isAuthenticated) {
    // Need to implement, e.g: call an api, etc...
  } else {
    // Need to implement, e.g: redirect user to sign in, etc..
  }
};

useEffect(() => {
  checkAuthenticate();
}, []);

const handleSignIn = async () => {
  const token = await client.login();

  if (token) {
    // Need to implement, e.g: call an api, etc...
  }
};

const handleSignUp = async () => {
  const token = await client.register();

  if (token) {
    // Need to implement, e.g: call an api, etc...
  }
};

const handleLogout = async () => {
  // With open web in your apps
  const isLoggedOut = await client.logout();

  if (isLoggedOut) {
    // Need to implement, e.g: redirect user to login screen, etc...
  }

  // Without open web in your apps
  const isLoggedOut = await client.logout();

  if (isLoggedOut) {
    // Need to implement, e.g: redirect user to login screen, etc...
  }
};

Get user information

To access the user information, use the getUserDetails helper function.

const userProfile = await client.getUserDetails();
console.log(userProfile);
// output: {"given_name":"Dave","id":"abcdef","family_name":"Smith","email":"dave@smith.com"}

View users in Kinde

Go to the Users page in Kinde to see your newly registered user.

User Permissions

Once a user has been verified, your product/application will return the JWT token with an array of permissions for that user. You will need to configure your product/application to read permissions and unlock the respective functions.

Set permissions in your Kinde account. Here's an example set of permissions.

const permissions = [
  "create:todos",
  "update:todos",
  "read:todos",
  "delete:todos",
  "create:tasks",
  "update:tasks",
  "read:tasks",
  "delete:tasks
];

We provide helper functions to more easily access permissions.

await client.getPermission("create:todos");
// {orgCode: "org_1234", isGranted: true}

await client.getPermissions();
// {orgCode: "org_1234", permissions: ["create:todos", "update:todos", "read:todos"]}

A practical example in code might look something like.

if ((await client.getPermission("create:todos")).isGranted) {
  // show Create Todo button in UI
}

Audience

An audience is the intended recipient of an access token - for example the API for your application. The audience argument can be passed to the Kinde client to request an audience be added to the token.

The audience of a token is the intended recipient of the token.

const client = new KindeSDK(
  YOUR_KINDE_ISSUER,
  YOUR_KINDE_REDIRECT_URI,
  YOUR_KINDE_CLIENT_ID,
  YOUR_KINDE_LOGOUT_REDIRECT_URI,
  YOUR_SCOPES,
  {
    audience: "api.yourapp.com"
  }
);

For details on how to connect, see Register an API.

Overriding scope

By default the KindeSDK requests the following scopes:

  • profile
  • email
  • offline
  • openid

You can override this by passing scope into the KindeSDK.

const client = new KindeSDK(
  YOUR_KINDE_ISSUER,
  YOUR_KINDE_REDIRECT_URI,
  YOUR_KINDE_CLIENT_ID,
  YOUR_KINDE_LOGOUT_REDIRECT_URI,
  "profile email offline openid
);

Getting claims

We have provided a helper to grab any claim from your id or access tokens. The helper defaults to access tokens:

await client.getClaim("aud");
// { name: "aud", value ["api.yourapp.com"] }

await client.getClaim("given_name", "id_token");
// { name: "given_name", value: "David" }

Organizations

Create an organization

To create a new organization within your application, you will need to run a similar function to this.

<Button title="Create Organization" onPress={handleCreateOrg} />

Then define the function of the button.

Make sure you've already defined KindeSDK as the client in the state.

const handleCreateOrg = () => {
  client.createOrg();
};

// You can also pass `org_name` as your organization
client.createOrg({org_name: "Your Organization"});

Sign in and sign up to organizations

Kinde has a unique code for every organization. You'll have to pass this code through when you register a new user.

Example function below:

client.register({orgCode: "your_org_code"});

If you want a user to sign in into a particular organization, pass this code along with the sign in method.

client.login({orgCode: "your_org_code"});

Following authentication, Kinde provides a json web token (jwt) to your application. Along with the standard information we also include the org_code and the permissions for that organization (this is important as a user can belong to multiple organizations and have different permissions for each). Example of a returned token:

Example of a returned token:

{
    "aud": [],
    "exp": 1658475930,
    "iat": 1658472329,
    "iss": "https://your_subdomain.kinde.com",
    "jti": "123457890",
    "org_code": "org_1234",
    "permissions": ["read:todos", "create:todos"],
    "scp": ["openid", "profile", "email", "offline"],
    "sub": "kp:123457890"
}

The id_token will also contain an array of organizations that a user belongs to - this is useful if you wanted to build out an organization switcher for example.

{
  ...
  "org_codes": ["org_1234", "org_4567"]
  ...
}

There are two helper functions you can use to extract information.

await client.getOrganization();
// {orgCode: "org_1234"}

await client.getUserOrganizations();
// {orgCodes: ["org_1234", "org_abcd"]}

For more information about how organizations work in Kinde, see Kinde organizations for developers.

Feature Flags

We have provided a helper to return any features flag from the access token:

client.getFlag('theme')
// returns
{
		"is_default": false
  	"value": "pink",
  	"code": "theme",
  	"type": "string",
}

client.getFlag('no-feature-flag')
// Error: This flag 'no-feature-flag' was not found, and no default value has been provided

client.getFlag('no-feature-flag', 'default-value')
// returns
{
		"is_default": true
		"code": "no-feature-flag",
		"value": "default-value",
}

client.getFlag('theme', 'default-theme', 'b')
// Error: Flag 'theme' is type string - requested type boolean

We also require wrapper functions by type which should leverage getFlag above.

Get boolean flags

/**
 * Get a boolean flag from the feature_flags claim of the access_token.
 * @param {String} code - The name of the flag.
 * @param {Boolean} [defaultValue] - A fallback value if the flag isn't found.
 * @return {Boolean}
 */
kindeClient.getBooleanFlag(code, defaultValue);

kindeClient.getBooleanFlag("is_dark_mode");
// true

kindeClient.getBooleanFlag("is_dark_mode", false);
// true

kindeClient.getBooleanFlag("new_feature");
// Error: This flag 'new_feature' was not found, and no default value has been provided

kindeClient.getBooleanFlag("new_feature", false);
// false (flag does not exist so falls back to default)

kindeClient.getBooleanFlag("theme", "blue");
// Error: Flag 'theme' is type string - requested type boolean

Get string flags

/**
 * Get a string flag from the feature_flags claim of the access_token.
 * @param {String} code - The name of the flag.
 * @param {String} [defaultValue] - A fallback value if the flag isn't found.
 * @return {String}
 */
kindeClient.getStringFlag(code, defaultValue);

/* Example usage */
kindeClient.getStringFlag("theme");
// pink

kindeClient.getStringFlag("theme", "black");
// true

kindeClient.getStringFlag("cta_color");
// Error: This flag 'cta_color' was not found, and no default value has been provided

kindeClient.getStringFlag("cta_color", "blue");
// blue (flag does not exist so falls back to default)

kindeClient.getStringFlag("is_dark_mode", false);
// Error: Flag 'is_dark_mode' is type string - requested type boolean

Get integer flags

/**
 * Get an integer flag from the feature_flags claim of the access_token.
 * @param {String} code - The name of the flag.
 * @param {Integer} [defaultValue] - A fallback value if the flag isn't found.
 * @return {Integer}
 */
kindeClient.getIntegerFlag(code, defaultValue);

kindeClient.getIntegerFlag("competitions_limit");
// 5

kindeClient.getIntegerFlag("competitions_limit", 3);
// 5

kindeClient.getIntegerFlag("team_count");
// Error: This flag 'team_count' was not found, and no default value has been provided

kindeClient.getIntegerFlag("team_count", 2);
// 2 (flag does not exist so falls back to default)

kindeClient.getIntegerFlag("is_dark_mode", false);
// Error: Flag 'is_dark_mode' is type boolean - requested type integer+

Token Storage

Once the user has successfully authenticated, you'll have a JWT and a refresh token and that has been stored securely. E.g. using the getAccessToken method of the Storage class to get an access token.

...
import { Storage } from '@kinde-oss/react-native-sdk-0-7x'
...

const accessToken = await Storage.getAccessToken();
console.log('access_token', accessToken);

We're using the react-native-keychain for React Native

The storage handler can be found at: Storage class

How to test

Run the test suite using the following command at the root of your React Native.

Note: Ensure you have already run npm install or equivalent.

SDK API Reference

issuer

Either your Kinde URL or your custom domain. e.g https://yourapp.kinde.com.

Type: string

Required: Yes

redirectUri

The URL that the user will be returned to after authentication.

Type: string

Required: Yes

clientId

The unique ID of your application in Kinde.

Type: string

Required: Yes

logoutRedirectUri

Where your user will be redirected when they sign out.

Type: string

Required: Yes

scope

The scopes to be requested from Kinde.

Type: boolean

Required: No

Default: openid profile email offline

additionalParameters

Additional parameters that will be passed in the authorization request.

Type: object

Required: No

Default: {}

additionalParameters - audience

The audience claim for the JWT.

Type: string

Required: No

KindeSDK methods

login

Constructs a redirect URL and sends the user to Kinde to sign in.

Arguments:

{
  audience?: string;
  isCreateOrg?: boolean;
  orgCode?: string;
  orgName?: string;
  connectionId?: string;
  lang?: string;
  loginHint?: string;
}

Usage:

await kinde.login();
// or
await kinde.login({orgCode: "your organization code"});

Allow orgCode to be provided if a specific organization is being signed into.

Sample output:

{
	"access_token": "eyJhbGciOiJSUzI...",
	"expires_in": 86400,
	"id_token": "eyJhbGciOiJSU...",
	"refresh_token": "yXI1bFQKbXKLD7AIU...",
	"scope": "openid profile email offline",
	"token_type": "bearer"
}

register

Constructs a redirect URL and sends the user to Kinde to sign up.

Arguments:

{
  audience?: string;
  isCreateOrg?: boolean;
  orgCode?: string;
  orgName?: string;
  connectionId?: string;
  lang?: string;
  loginHint?: string;
}

Usage:

await kinde.register();
// or
await kinde.register({orgCode: "your organization code"});

Allow orgCode to be provided if a specific organization is being registered to.

Sample output:

{
	"access_token": "eyJhbGciOiJSUzI...",
	"expires_in": 86400,
	"id_token": "eyJhbGciOiJSU...",
	"refresh_token": "yXI1bFQKbXKLD7AIU...",
	"scope": "openid profile email offline",
	"token_type": "bearer"
}

logout

Logs the user out of Kinde.

Arguments:

isRevoke: boolean; // default is false

Usage:

await kinde.logout();
// or
await kinde.logout(true);

Sample output: true or false

getToken

Returns the raw Access token from URL after logged from Kinde.

Arguments:

url?: string

Usage:

await kinde.getToken(url);
// or
await kinde.getToken();

You need to have already authenticated. Otherwise, an error will occur.

Sample output:

{
	"access_token": "eyJhbGciOiJSUzI...",
	"expires_in": 86400,
	"id_token": "eyJhbGciOiJSU...",
	"refresh_token": "yXI1bFQKbXKLD7AIU...",
	"scope": "openid profile email offline",
	"token_type": "bearer"
}

createOrg

Constructs a redirect URL and sends the user to Kinde to sign up and create a new organization in your business.

Arguments:

{
	org_name?: string
}

Usage:

await kinde.createOrg(); 
// or 
await kinde.createOrg({org_name: 'your organization name'}); _**//**_

Allow org_name to be provided if you want a specific organization name when you create.

Sample output:

{
	"access_token": "eyJhbGciOiJSUzI...",
	"expires_in": 86400,
	"id_token": "eyJhbGciOiJSU...",
	"refresh_token": "yXI1bFQKbXKLD7AIU...",
	"scope": "openid profile email offline",
	"token_type": "bearer"
}

getClaim

Gets a claim from an access or ID token.

Arguments:

claim: string;
tokenKey?: string

Usage:

await kinde.getClaim("given_name", "id_token");

Sample output:

{ name: "give_name", value: "David"}

getPermission

Returns the state of a given permission.

Arguments: key: string

Usage:

await kinde.getPermission("read:todos");

Sample output:

{
	"orgCode": "org_1234",
	"isGranted": true
}

getPermissions

Returns all permissions for the current user for the organization they are signed into.

Usage:

await kinde.getPermissions();

Sample output:

{
	"orgCode":"org_1234",
	"permissions": ["create:todos","update:todos","read:todos"]
}

getOrganization

Get details for the organization your user is signed into.

Usage:

await kinde.getOrganization();

Sample output:

{
	"orgCode": "org_1234"
}

getUserDetails

Returns the profile for the current user.

Usage:

await kinde.getUserDetails();

Sample output:

{
	"given_name": "Dave",
	"id": "abcdef",
	"family_name": "Smith",
	"email": "dave@smith.com"
}

getUserOrganizations

Gets an array of all organizations the user has access to.

Usage:

await kinde.getUserOrganizations();

Sample output:

{ "orgCodes": ["org1234", "org5678"] }

isAuthenticated

Return the boolean to demonstrate whether the user is authenticated or not.

Usage:

await kinde.isAuthenticate;

Sample output: true or false

getFlag

Get a flag from the feature_flags claim of the access_token.

Arguments:

flagName : string;
options? :  OptionalFlag = {}
flagType? : FlagType


type FlagType = 's' | 'b' | 'i';

type OptionalFlag = {
	defaultValue?: string | boolean | number
}

Usage:

kinde.getFlag("theme");

Sample output:

{
    "code": "theme",
    "type": "string",
    "value": "pink",
    "is_default": false
}

getBooleanFlag

Get a boolean flag from the feature_flags claim of the access token

Arguments:

flagName: string
defaultValue?: boolean

Usage:

kinde.getBooleanFlag("is_dark_mode");

Sample output: true

getStringFlag

Get a string flag from the feature_flags claim of the access token

Arguments:

flagName: string
defaultValue?: string

Usage:

kinde.getStringFlag("theme");

Sample output: black

getIntegerFlag

Get a integer flag from the feature_flags claim of the access token

Arguments:

flagName: string
defaultValue?: number

Usage:

kinde.getIntegerFlag("team_count");

Sample output: 2

General tips

Building issues

'value' is unavailable: introduced in iOS 12.0

If you got the error 'value' is unavailable: introduced in iOS 12.0 when trying to build the app, you can follow the below steps to fix that:

  1. In your Xcode project navigator, select Pods.
  2. Under Targets, select React-Codegen.
  3. Select the Build Settings tab.
  4. Under Deployment, set iOS Deployment Target to 12.4.
  5. Clean project and rebuild: Product > Clean Build Folder, Product > Build.

  1. Dependency 'androidx.browser:browser:1.6.0-beta01' requires libraries and applications that depend on it to compile against version 34 or later of the Android APIs

    The solution is add androidXBrowser = "1.4.0" in your project.

    // android/build.gradle
    buildscript {
        ...
        ext {
            // ...
            androidXBrowser = "1.4.0
            // ....
        }
        ...
    }
  2. Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.7.22 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.22)

    The solution is add org.jetbrains.kotlin:kotlin-bom:1.8.0 dependency in your project.

    // android/app/build.grade
    dependencies {
        ...
        implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
        ...
    }
    

Caching issues

Sometimes there will be issues related to caching when you develop React Native. There are some recommendations for cleaning the cache:

  1. Remove node_modules, yarn.lock or package-lock.json.
  2. Clean cache: yarn cache clean or npm cache clean --force.
  3. Make sure you have changed values in .env file.
  4. Trying to install packages again: yarn install or npm install.
  5. Run Metro Bundler: 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 clean
    

Clean cache for iOS

  1. Run this:

    cd <StarterKit_PATH>/ios
    rm -rf Pods && rm Podfile.lock
    
  2. Clean build folders on Xcode.

If you need help connecting to Kinde, please contact us at support@kinde.com.