> ## Documentation Index
> Fetch the complete documentation index at: https://resources.begenuin.com/llms.txt
> Use this file to discover all available pages before exploring further.

# React Native SDK

> The genuin-react-native SDK is designed to seamlessly integrate the features of the "Genuin" mobile application into your own React Native projects. Follow the instructions below to install and integrate the SDK into your application.

# Installation

Run the below code to install the react native

<CodeGroup>
  ```
  npm install genuin-react-native
  ```
</CodeGroup>

# Android

To install the React Native in Android perform the below steps:

### Android Configuration

**Step 1**: In `android/app/build.gradle`:

<CodeGroup>
  ```kotlin build.gradle theme={null}

  android {
      defaultConfig {
          minSdk = 24
      }
  }

  ```
</CodeGroup>

**Step 2**: In `android/app/src/main/AndroidManifest.xml`:

<CodeGroup>
  ```kotlin AndroidManifest.xml theme={null}

  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools">

  <uses-permission android:name="android.permission.INTERNET" />

  <!-- 1. Add tools:remove="android:taskAffinity"
       2. Add android:allowBackup="false" -->

  <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme"
      tools:remove="android:taskAffinity"
      android:supportsRtl="true">

      <activity
          android:name=".MainActivity"
          android:label="@string/app_name"
          android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
          android:launchMode="singleTask"
          android:windowSoftInputMode="adjustResize"
          android:exported="true">
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
      </activity>
  </application>
  </manifest>

  ```
</CodeGroup>

**Step 3**: Change theme in `android/app/src/main/res/values/styles.xml`:

<Note>
  Our SDK is using Material components so in order to use our sdk you need to use material theme as shown in below example
</Note>

<CodeGroup>
  ```kotlin styles.xml theme={null}

  <?xml version="1.0" encoding="utf-8"?>
  <resources>
      <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
      <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
          <!-- Show a splash screen on the activity. Automatically removed when
               the Flutter engine draws its first frame -->
          <item name="android:windowBackground">@drawable/launch_background</item>
      </style>

  </resources>

  ```
</CodeGroup>

**Step 4**: Create `android/app/proguard-rules.pro`, add the following lines:

<CodeGroup>
  ```kotlin proguard-rules.pro theme={null}

  # Add project specific ProGuard rules here.
  # By default, the flags in this file are appended to flags specified
  # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
  # You can edit the include path and order by changing the proguardFiles
  # directive in build.gradle.
  #
  # For more details, see
  #   http://developer.android.com/guide/developing/tools/proguard.html

  # Add any project specific keep options here:
  -dontwarn com.facebook.imagepipeline.nativecode.WebpTranscoder

  -keep class com.bumptech.glide.**{*;}
  -keep public class * {
      public *;
      protected *;
  }

  # Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
  # EnclosingMethod is required to use InnerClasses.
  -keepattributes Signature, InnerClasses, EnclosingMethod

  # Retrofit does reflection on method and parameter annotations.
  -keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations

  # Retain service method parameters when optimizing.
  -keepclassmembers,allowshrinking,allowobfuscation interface * {
      @retrofit2.http.* <methods>;
  }

  # Ignore annotation used for build tooling.
  -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

  # Ignore JSR 305 annotations for embedding nullability information.
  -dontwarn javax.annotation.**

  # Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
  -dontwarn kotlin.Unit

  # Top-level functions that can only be used by Kotlin.
  -dontwarn retrofit2.KotlinExtensions
  -dontwarn java.lang.reflect.AnnotatedType
  -dontwarn com.google.api.client.http.GenericUrl
  -dontwarn com.google.api.client.http.HttpHeaders
  -dontwarn com.google.api.client.http.HttpRequest
  -dontwarn com.google.api.client.http.HttpRequestFactory
  -dontwarn com.google.api.client.http.HttpResponse
  -dontwarn com.google.api.client.http.HttpTransport
  -dontwarn com.google.api.client.http.javanet.NetHttpTransport$Builder
  -dontwarn com.google.api.client.http.javanet.NetHttpTransport
  -dontwarn com.squareup.picasso.Picasso
  -dontwarn com.squareup.picasso.RequestCreator
  -dontwarn java.awt.image.BufferedImage
  -dontwarn javax.imageio.ImageIO
  -dontwarn org.joda.time.Instant
  -dontwarn org.junit.Assert
  -dontwarn org.slf4j.impl.StaticLoggerBinder
  -dontwarn org.slf4j.impl.StaticMDCBinder
  -dontwarn org.slf4j.impl.StaticMarkerBinder

  # With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
  # and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
  -if interface * { @retrofit2.http.* <methods>; }
  -keep,allowobfuscation interface <1>


  ##---------------Begin: proguard configuration for Gson  ----------
  # Gson uses generic type information stored in a class file when working with fields. Proguard
  # removes such information by default, so configure it to keep all of it.
  -keepattributes Signature

  # For using GSON @Expose annotation
  -keepattributes *Annotation*

  # Gson specific classes
  -dontwarn sun.misc.**
  #-keep class com.google.gson.stream.** { *; }

  # Application classes that will be serialized/deserialized over Gson
  -keep class com.begenuin.begenuin.data.model.** { <fields>; }
  -keep class com.begenuin.begenuin.vo.** { <fields>; }


  # RenderScript
  -keepclasseswithmembernames class * {
  native <methods>;
  }
  -keep class androidx.renderscript.** { *; }

  -keepattributes *Annotation*

  -keep class com.giphy.sdk.core.models.** { *; }
  -keep class com.giphy.sdk.ui.views.** { *; }

  -keep public class * implements java.lang.reflect.Type

  -keep class com.google.mediapipe.solutioncore.** {*;}
  -keep class com.google.protobuf.** {*;}

  -dontwarn com.begenuin.sdk.BR
  -dontwarn com.google.android.play.core.splitcompat.SplitCompatApplication
  -dontwarn com.google.android.play.core.splitinstall.SplitInstallManager
  -dontwarn com.google.android.play.core.splitinstall.SplitInstallManagerFactory
  -dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest$Builder
  -dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest
  -dontwarn com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener
  -dontwarn com.google.android.play.core.tasks.OnFailureListener
  -dontwarn com.google.android.play.core.tasks.OnSuccessListener
  -dontwarn com.google.android.play.core.tasks.Task
  -dontwarn com.google.mediapipe.proto.CalculatorProfileProto$CalculatorProfile
  -dontwarn com.google.mediapipe.proto.GraphTemplateProto$CalculatorGraphTemplate
  -dontwarn javax.lang.model.AnnotatedConstruct
  -dontwarn javax.lang.model.SourceVersion
  -dontwarn javax.lang.model.element.AnnotationMirror
  -dontwarn javax.lang.model.element.AnnotationValue
  -dontwarn javax.lang.model.element.AnnotationValueVisitor
  -dontwarn javax.lang.model.element.Element
  -dontwarn javax.lang.model.element.ElementKind
  -dontwarn javax.lang.model.element.ElementVisitor
  -dontwarn javax.lang.model.element.ExecutableElement
  -dontwarn javax.lang.model.element.Name
  -dontwarn javax.lang.model.element.NestingKind
  -dontwarn javax.lang.model.element.PackageElement
  -dontwarn javax.lang.model.element.QualifiedNameable
  -dontwarn javax.lang.model.element.TypeElement
  -dontwarn javax.lang.model.element.TypeParameterElement
  -dontwarn javax.lang.model.element.VariableElement
  -dontwarn javax.lang.model.type.ArrayType
  -dontwarn javax.lang.model.type.DeclaredType
  -dontwarn javax.lang.model.type.ErrorType
  -dontwarn javax.lang.model.type.ExecutableType
  -dontwarn javax.lang.model.type.IntersectionType
  -dontwarn javax.lang.model.type.NoType
  -dontwarn javax.lang.model.type.NullType
  -dontwarn javax.lang.model.type.PrimitiveType
  -dontwarn javax.lang.model.type.TypeKind
  -dontwarn javax.lang.model.type.TypeMirror
  -dontwarn javax.lang.model.type.TypeVariable
  -dontwarn javax.lang.model.type.TypeVisitor
  -dontwarn javax.lang.model.type.WildcardType
  -dontwarn javax.lang.model.util.AbstractElementVisitor8
  -dontwarn javax.lang.model.util.ElementFilter
  -dontwarn javax.lang.model.util.Elements
  -dontwarn javax.lang.model.util.SimpleAnnotationValueVisitor8
  -dontwarn javax.lang.model.util.SimpleElementVisitor8
  -dontwarn javax.lang.model.util.SimpleTypeVisitor8
  -dontwarn javax.lang.model.util.Types
  -dontwarn javax.tools.Diagnostic$Kind
  -dontwarn javax.tools.JavaFileObject$Kind
  -dontwarn javax.tools.JavaFileObject
  -dontwarn javax.tools.SimpleJavaFileObject

  ```
</CodeGroup>

<Tip>
  Want to override our default loader?

  We are using `lottie` animation for our loader. You can put your custom lottie animation loader with the name `loader_mix.json` in the `android/app/src/main/res/raw` folder. Make sure you use the same name as provided.
</Tip>

### Quick Start

**1. Initialize SDK**

<CodeGroup>
  ```kotlin theme={null}

  import android.content.Intent
  import android.os.Bundle
  import com.facebook.react.ReactActivity
  import com.facebook.react.ReactActivityDelegate
  import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
  import com.facebook.react.defaults.DefaultReactActivityDelegate
  import com.genuinsdk.GenuinSDKPluginModule


  class MainActivity : ReactActivity() {

      /**
       * Returns the name of the main component registered from JavaScript. This is used to schedule
       * rendering of the component.
       */
      override fun getMainComponentName(): String = "YourApp"

      /**
       * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
       * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
       */
      override fun createReactActivityDelegate(): ReactActivityDelegate =
          DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          GenuinSDKPluginModule.initSDK(application, "YOUR_API_KEY")
      }
  }

  ```
</CodeGroup>

**2. Handling Deeplink**

To handle deep link place the below code in `android/app/src/main/AndroidManifest.xml` file:

<CodeGroup>
  ```kotlin AndroidManifest.xml theme={null}

  <activity
      android:name=".MainActivity"
      android:label="@string/app_name"
      android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
      android:launchMode="singleTask"
      android:windowSoftInputMode="adjustResize"
      android:exported="true">
      <intent-filter>
          <action android:name="android.intent.action.MAIN" />
          <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      <intent-filter android:autoVerify="true">
          <action android:name="android.intent.action.VIEW" />

          <category android:name="android.intent.category.DEFAULT" />
          <category android:name="android.intent.category.BROWSABLE" />

          <data android:host="YOUR_WHITE-LABELLED_DOMAIN" android:scheme="https" />
      </intent-filter>
  </activity>

  ```
</CodeGroup>

<CodeGroup>
  ```kotlin theme={null}

  import android.content.Intent
  import android.os.Bundle
  import com.facebook.react.ReactActivity
  import com.facebook.react.ReactActivityDelegate
  import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
  import com.facebook.react.defaults.DefaultReactActivityDelegate
  import com.genuinsdk.GenuinSDKPluginModule

  class MainActivity : ReactActivity() {

      /**
       * Returns the name of the main component registered from JavaScript. This is used to schedule
       * rendering of the component.
       */
      override fun getMainComponentName(): String = "YourApp"

      /**
       * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
       * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
       */
      override fun createReactActivityDelegate(): ReactActivityDelegate =
          DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          GenuinSDKPluginModule.initSDK(application, "YOUR_API_KEY")
          if (intent != null && intent.data != null) {
              handleDeepLink(intent)
          }
      }

      override fun onNewIntent(intent: Intent) {
          super.onNewIntent(intent)
          handleDeepLink(intent)
      }

      private fun handleDeepLink(intent: Intent?) {
          intent?.data?.let {
              GenuinSDKPluginModule.handleDeepLink(this@MainActivity, intent)
          }
      }
  }

  ```
</CodeGroup>

**3. Handling Push Notifications**

To handle the push notification place the below code In `android/app/build.gradle` file:

<CodeGroup>
  ```kotlin build.gradle theme={null}

  buildscript {
      dependencies {
          classpath("com.google.gms:google-services:4.4.2") 
      }
  }

  ```
</CodeGroup>

# iOS

### iOS Configuration

**1. In ios/Podfile**

<CodeGroup>
  ```swift ios/Podfile theme={null}

  ENV['USE_FRAMEWORKS'] = 'dynamic'

  # Resolve react_native_pods.rb with node to allow for hoisting
  require Pod::Executable.execute_command('node', ['-p',
    'require.resolve(
      "react-native/scripts/react_native_pods.rb",
      {paths: [process.argv[1]]},
    )', __dir__]).strip

  platform :ios, min_ios_version_supported
  prepare_react_native_project!

  linkage = ENV['USE_FRAMEWORKS']
  if linkage != nil
    Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
    use_frameworks! :linkage => linkage.to_sym
  end

  target 'YourApp' do
    config = use_native_modules!

    use_react_native!(
      :path => config[:reactNativePath],
      # An absolute path to your application root.
      :app_path => "#{Pod::Config.instance.installation_root}/.."
    )

    pre_install do |installer|
        installer.pod_targets.each do |pod|
          if pod.name.eql?('RNReanimated')
            def pod.build_type
            Pod::BuildType.static_library
          end
        end
      end
    end

    post_install do |installer|
      # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
      react_native_post_install(
        installer,
        config[:reactNativePath],
        :mac_catalyst_enabled => false,
        # :ccache_enabled => true
      )

      installer.pods_project.targets.each do |target|
        if target.name == 'Giphy'
          `xcrun -sdk iphoneos bitcode_strip -r Pods/Giphy/GiphySDK/GiphyUISDK.xcframework/ios-arm64_armv7/GiphyUISDK.framework/GiphyUISDK -o Pods/Giphy/GiphySDK/GiphyUISDK.xcframework/ios-arm64_armv7/GiphyUISDK.framework/GiphyUISDK`
        end
        target.build_configurations.each do |config|
          config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.1'
          config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
        end
      end

    end
  end
  ```
</CodeGroup>

### Quick Start

**1. Initialize SDK**

<CodeGroup>
  ```swift theme={null}

  import UIKit
  import React
  import React_RCTAppDelegate
  import ReactAppDependencyProvider
  import Firebase

  @main
  class AppDelegate: RCTAppDelegate, UNUserNotificationCenterDelegate {

    override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
      self.moduleName = "YourApp"
      self.dependencyProvider = RCTAppDependencyProvider()

      if FirebaseApp.app() == nil {
        FirebaseApp.configure()
      }

      UNUserNotificationCenter.current().delegate = self

      UIApplication.shared.registerForRemoteNotifications()

      // You can add your custom initial props in the dictionary below.
      // They will be passed down to the ViewController used by React Native.
      self.initialProps = [:]
      GenuinModuleObjCWrapper.initSDK("YOUR_API_KEY", loaderName: "YOUR_LOTTIE_LOADER_NAME", showNavigationBar: nil)
      addNavVC()
      return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    func addNavVC(){
      DispatchQueue.main.async {
        if let rootVC = self.window.rootViewController {
          self.window.rootViewController = nil
          let navVC = GenuinModuleObjCWrapper.getGenuinNavigationController(rootVC)
          navVC?.setNavigationBarHidden(true, animated: true);
          self.window.rootViewController = navVC
          self.window.makeKeyAndVisible()
        }
      }
    }

    override func sourceURL(for bridge: RCTBridge) -> URL? {
      self.bundleURL()
    }

    override func bundleURL() -> URL? {
  #if DEBUG
      RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
  #else
      Bundle.main.url(forResource: "main", withExtension: "jsbundle")
  #endif
    }

  }
  ```
</CodeGroup>

If your project has AppDelegate.swift file create the following wrapper classes in Objective-C in order to communicate with genuin's react-native module,

1. `GenuinModuleObjCWrapper.h`

```swift theme={null}

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface GenuinModuleObjCWrapper : NSObject
+ (void)initSDK:(NSString *_Nullable)apiKey loaderName:(NSString *_Nullable)loaderName showNavigationBar:(BOOL *_Nullable)showNavigationBar;
+ (BOOL)application:(UIApplication *_Nullable)application continueUserActivity:(NSUserActivity *_Nullable)userActivity restorationHandler:(void (^_Nullable)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler;
+ (BOOL)handleDeepLink:(NSURL * _Nullable)dlURL controller:(UIViewController * _Nullable)controller;
+ (void)handleForegroundNotification:(NSDictionary *)notificationData;
+ (UINavigationController*_Nullable)getGenuinNavigationController:(UIViewController*)viewController;
@end

NS_ASSUME_NONNULL_END

```

2. `GenuinModuleObjCWrapper.mm`

```swift theme={null}

#import "GenuinModuleObjCWrapper.h"
#import "GenuinSDKPlugin.h"

@implementation GenuinModuleObjCWrapper
+ (void)initSDK:(NSString *_Nullable)apiKey loaderName:(NSString *_Nullable)loaderName showNavigationBar:(BOOL *_Nullable)showNavigationBar {
  [GenuinSDKPlugin initSDK:apiKey loaderName:loaderName showNavigationBar:showNavigationBar];
}

+ (BOOL)application:(UIApplication *_Nullable)application continueUserActivity:(NSUserActivity *_Nullable)userActivity restorationHandler:(void (^_Nullable)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
  return [GenuinSDKPlugin application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
}

+ (BOOL)handleDeepLink:(NSURL * _Nullable)dlURL controller:(UIViewController * _Nullable)controller {
  return [GenuinSDKPlugin handleDeepLink:dlURL controller:controller];
}

+ (void)handleForegroundNotification:(NSDictionary *)notificationData {
  [GenuinSDKPlugin handleForegroundNotification:notificationData];
}

+ (UINavigationController*_Nullable)getGenuinNavigationController:(UIViewController*)viewController {
  return [GenuinSDKPlugin getGenuinNavigationController: viewController];
}

@end

```

3. `YourApp-Bridging-Header.h`

```swift theme={null}

#import "GenuinModuleObjCWrapper.h"

```

**2. Handling Deep Link**

To handle deeplink place the below in `AppDelegate.swift` file:

Prerequisite step : [Link](https://resources.begenuin.com/developers/sdk-docs/ios_sdk#handling-deep-link)

In `AppDelegate.swift`:

<CodeGroup>
  ```swift AppDelegate.swift theme={null}

  import UIKit
  import React
  import React_RCTAppDelegate
  import ReactAppDependencyProvider
  import Firebase

  @main
  class AppDelegate: RCTAppDelegate, UNUserNotificationCenterDelegate {

    override func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([any UIUserActivityRestoring]?) -> Void) -> Bool {
      let result = GenuinModuleObjCWrapper.application(application, continue: userActivity, restorationHandler: restorationHandler)
      if GenuinModuleObjCWrapper.handleDeepLink(userActivity.webpageURL, controller: window.rootViewController) {
          return true
      }
      return result
    }

  }

  ```
</CodeGroup>

**3. Handling Push Notification**

To handle the push notification place the below code In `AppDelegate.swift` file:

<CodeGroup>
  ```swift AppDelegate.swift theme={null}

  import UIKit
  import React
  import React_RCTAppDelegate
  import ReactAppDependencyProvider
  import Firebase

  @main
  class AppDelegate: RCTAppDelegate, UNUserNotificationCenterDelegate {

    override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
      Messaging.messaging().apnsToken = deviceToken
      print("deviceToken", deviceToken)
    }

    override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("\(userInfo )")
        completionHandler(.newData)
    }

    override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: any Error) {
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
      completionHandler([.list, .banner, .badge, .sound])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
      if response.notification.request.trigger == nil {
        let notificationData = ["data": response.notification.request.content.userInfo]
          GenuinModuleObjCWrapper.handleForegroundNotification(notificationData)
      }
      completionHandler()
    }

  }

  ```
</CodeGroup>

# Web

### Web Configuration

To integrate the `genuin-react-native` SDK into your application, follow these steps:

1. Import the Feed Component: In your `app.jsx` file, import the `Feed` component from the `genuin-react-native` SDK.
2. Obtain Your API Key: Contact the Genuin team to obtain your unique `API_KEY`. This key is essential for authenticating your application with the Genuin service.
3. Implement the `Feed` Component: Use the Feed component within your application, passing the `API_KEY` as a prop. Below is an example of how to implement this:

<CodeGroup>
  ```javascript javascript  theme={null}
  import React from "react";
  import Feed from "genuin-react-native";

  export default function App() {
    return <Feed apiKey="API_KEY" />;
  }
  ```
</CodeGroup>

**Carousel**

```javascript javascript theme={null}
import React from "react";
import Carousel from "genuin-react-native";

export default function App() {
  return <Carousel apiKey="API_KEY" />;
}
```

**Example**

Here's a complete example of how your `app.jsx` file might look:

<CodeGroup>
  ```javascript javascript theme={null}
  import React from "react";
  import { SafeAreaView, StyleSheet, Text } from "react-native";
  import Feed from "genuin-react-native";

  export default function App() {
    return (
      <SafeAreaView style={styles.container}>
        <Text style={styles.header}>Welcome to the Genuin Feed</Text>
        <Feed apiKey="YOUR_API_KEY_HERE" />
      </SafeAreaView>
    );
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: "center",
      alignItems: "center",
      backgroundColor: "#F5FCFF",
    },
    header: {
      fontSize: 20,
      textAlign: "center",
      margin: 10,
    },
  });
  ```
</CodeGroup>

**Additonal Information**

**Handling Errors**
Ensure you handle any potential errors gracefully. The Feed component can throw errors if the API key is invalid or if there are network issues. Implement error handling in your component as needed.

**Styling the Feed**
You can style the Feed component using standard React Native styling techniques. Customize it to fit the design and aesthetics of your application.

**Updating the API Key**
If you need to update your API key, simply modify the `apiKey` prop passed to the Feed component. Ensure your application is reloaded to apply the changes.

# React Native

**1. Load Carousel Embed View**

<CodeGroup>
  ```

  import React, { useRef } from 'react';
  import { Carousel, PlayPauseRef } from 'genuin-react-native';

  export default function App() {
    const carouselRef = useRef<PlayPauseRef>(null);
    return <Carousel ref={carouselRef} style={{height:400, width:'100%'}} embedId='YOUR_EMBED_ID' uniqueId='UNIQUE_ID' ssoToken='YOUR_SSO_TOKEN' isShowProfileEnabled={false} isDirectDeepLinkEnabled={false}  />;
  }

  ```
</CodeGroup>

<Note>
  **Note**: 1. You can set height and width of the Carousel as per your need.
  2\. You can use `carouselRef.current?.pause()` and `carouselRef.current?.resume()` for pause and resume video play in Carousel.
</Note>

To configure the EmbedParams based on your need you can pass the below values.

**embedId** = The Embed Id that you want to load.

**uniqueId** = This is an optional parameter. This uniqueId is used when we need to display same embed in multiple/same screen. We need to provide uniqueId for the same embedId in multiple/same screen.

**ssoToken** = This is an optional parameter. To auto login in the SDK, you shall pass “YOUR\_SSO\_TOKEN” in order to implement Embed with SSO in your app.

**interactionDeepLink** = This is an optional parameter. You can pass a deeplink URL in this parameter. If a deeplink URL is given then all the interaction/clicks in the full screen view will redirect to the deeplink URL given. If not passed then the regular flow will work. It should be a correct URL else user will not be redirected.

**isDirectDeepLinkEnabled** = This is an optional boolean parameter. Default value is false. If this parameter is true then all the interaction/clicks in the full screen view will redirect to the specific video in white labelled app associated with video and also value of this parameter “interactionDeepLink” will be ignored. If not passed then the regular flow will work.

<Note>
  **Note**: For using isDirectDeepLinkEnabled parameter, you must have white labelled your domain first and also integrated the Handling deep link part in your main app in which you want to redirect this video to.
</Note>

**isShowProfileEnabled** = This is an optional boolean parameter. Default value is false. If this parameter is true and also if user is logged in than Profile picture will be visible in full screen view (right side top corner). On clicking the profile picture user will see the account settings and logout options.

**2. Load Standard Wall Embed View**

<CodeGroup>
  ```

  import React, { useRef } from 'react';
  import { PlayPauseRef, StandardWall } from 'genuin-react-native';

  export default function App() {
    const standardWallRef = useRef<PlayPauseRef>(null);
    return <StandardWall ref={standardWallRef} style={{height:'100%', width:'100%'}} embedId='YOUR_EMBED_ID' uniqueId='UNIQUE_ID' ssoToken='YOUR_SSO_TOKEN' isShowProfileEnabled={false} isDirectDeepLinkEnabled={false}  />;
  }

  ```
</CodeGroup>

<Note>
  **Note**: 1. You can set height and width of the StandardWall as per your need.
  2\. You can use `standardWallRef.current?.pause()` and `standardWallRef.current?.resume()` for pause and resume video play in StandardWall.
</Note>

To configure the EmbedParams based on your need you can pass the below values.

**embedId** = The Embed Id that you want to load.

**uniqueId** = This is an optional parameter. This uniqueId is used when we need to display same embed in multiple/same screen. We need to provide uniqueId for the same embedId in multiple/same screen.

**ssoToken** = This is an optional parameter. To auto login in the SDK, you shall pass “YOUR\_SSO\_TOKEN” in order to implement Embed with SSO in your app.

**interactionDeepLink** = This is an optional parameter. You can pass a deeplink URL in this parameter. If a deeplink URL is given then all the interaction/clicks in the full screen view will redirect to the deeplink URL given. If not passed then the regular flow will work. It should be a correct URL else user will not be redirected.

**isDirectDeepLinkEnabled** = This is an optional boolean parameter. Default value is false. If this parameter is true then all the interaction/clicks in the full screen view will redirect to the specific video in white labelled app associated with video and also value of this parameter “interactionDeepLink” will be ignored. If not passed then the regular flow will work.

**Note**: For using isDirectDeepLinkEnabled parameter, you must have white labelled your domain first and also integrated the Handling deep link part in your main app in which you want to redirect this video to.

**isShowProfileEnabled** = This is an optional boolean parameter. Default value is false. If this parameter is true and also if user is logged in than Profile picture will be visible in full screen view (right side top corner). On clicking the profile picture user will see the account settings and logout options.

**3. Load FullScreen Embed View**

<CodeGroup>
  ```

  import React, { useRef } from 'react';
  import { Feed, PlayPauseRef } from 'genuin-react-native';

  export default function App() {
    const feedRef = useRef<PlayPauseRef>(null);
    return <Feed ref={feedRef} style={{height:'100%', width:'100%'}} embedId='YOUR_EMBED_ID' uniqueId='UNIQUE_ID' ssoToken='YOUR_SSO_TOKEN' isShowProfileEnabled={false} isDirectDeepLinkEnabled={false}  />;
  }

  ```
</CodeGroup>

<Note>
  **Note**: 1. You can set height and width of the Feed as per your need.
  2\. You can use `feedRef.current?.pause()` and `feedRef.current?.resume()` for pause and resume video play in Feed.
</Note>

To configure the EmbedParams based on your need you can pass the below values.

**embedId** = The Embed Id that you want to load.

**uniqueId** = This is an optional parameter. This uniqueId is used when we need to display same embed in multiple/same screen. We need to provide uniqueId for the same embedId in multiple/same screen.

**ssoToken** = This is an optional parameter. To auto login in the SDK, you shall pass “YOUR\_SSO\_TOKEN” in order to implement Embed with SSO in your app.

**interactionDeepLink** = This is an optional parameter. You can pass a deeplink URL in this parameter. If a deeplink URL is given then all the interaction/clicks in the full screen view will redirect to the deeplink URL given. If not passed then the regular flow will work. It should be a correct URL else user will not be redirected.

**isDirectDeepLinkEnabled** = This is an optional boolean parameter. Default value is false. If this parameter is true then all the interaction/clicks in the full screen view will redirect to the specific video in white labelled app associated with video and also value of this parameter “interactionDeepLink” will be ignored. If not passed then the regular flow will work.

**Note**: For using isDirectDeepLinkEnabled parameter, you must have white labelled your domain first and also integrated the Handling deep link part in your main app in which you want to redirect this video to.

**isShowProfileEnabled** = This is an optional boolean parameter. Default value is false. If this parameter is true and also if user is logged in than Profile picture will be visible in full screen view (right side top corner). On clicking the profile picture user will see the account settings and logout options.

**4. Load HomeFeed View(Android Specific)**

<CodeGroup>
  ```

  import React, { useRef } from 'react';
  import { HomeFeed, PlayPauseRef } from 'genuin-react-native';

  export default function App() {
    const homeFeedRef = useRef<PlayPauseRef>(null);
    return <HomeFeed ref={homeFeedRef} style={{height:'100%', width:'100%'}}  />;
  }

  ```
</CodeGroup>

<Note>
  **Note**: 1. You can set height and width of the HomeFeed as per your need.
  2\. You can use `homeFeedRef.current?.pause()` and `homeFeedRef.current?.resume()` for pause and resume video play in HomeFeed.
</Note>

**5. Handling Push Notifications**

**Prerequisite:**

Create firebase project and integrate into your app by following <u> [https://firebase.google.com/docs/flutter/setup](https://firebase.google.com/docs/flutter/setup) </u>

Step1: Create `firebase_options.dart` in lib folder and add below details in that file.

<CodeGroup>
  ```

  import 'package:firebase_core/firebase_core.dart';

  class DefaultFirebaseOptions {
    static FirebaseOptions get currentPlatform {
      if (Platform.isAndroid) {
        return const FirebaseOptions(
          apiKey: 'YOUR-ANDROID-API-KEY',
          appId: 'YOUR-ANDROID-APP-ID',
          messagingSenderId: 'YOUR-SENDER-ID',
          projectId: 'YOUR-PROJECT-ID',
          storageBucket: 'YOUR-STORAGE-BUCKET',
        );
      }else{
        return const FirebaseOptions(
          apiKey: 'YOUR-IOS-API-KEY',
          appId: 'YOUR-IOS-APP-ID',
          messagingSenderId: 'YOUR-SENDER-ID',
          projectId: 'YOUR-PROJECT-ID',
          storageBucket: 'YOUR-STORAGE-BUCKET',
        );
      }
    }
  }

  ```
</CodeGroup>

Step 2: Handling background/foreground notifications

**Note**: Here for Android you need to provide small notification icon as "icon" key for foreground notifications. This icon needs to be in your flutter as well as android folder.

<CodeGroup>
  ```

  import 'package:firebase_core/firebase_core.dart';
  import 'package:firebase_messaging/firebase_messaging.dart';
  import 'package:genuin_sdk/genuin_sdk.dart';
  import 'firebase_options.dart';

  // This method will be called when app is in background and push received
  Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
    await Firebase.initializeApp();
  }

  final _genuinSdkPlugin = GenuinSdk();

  Future<void> main() async {
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp(
      name: 'YOUR_FIREBASE_PROJECT_NAME',
      options: DefaultFirebaseOptions.currentPlatform,
    );
    final messaging = FirebaseMessaging.instance;

    // Asking push notification permission
    final settings = await messaging.requestPermission(
      alert: true,
      announcement: false,
      badge: true,
      carPlay: false,
      criticalAlert: false,
      provisional: false,
      sound: true,
    );

    // If permission is granted than get firebase token and register it with Genuin SDK
    if (settings.authorizationStatus == AuthorizationStatus.authorized) {
      String? token = await messaging.getToken();
      if (token != null) {
        await _genuinSdkPlugin.registerFCMToken(token);
      }
    }

    // Check for initial notification that opened the app
    RemoteMessage? initialMessage =
    await FirebaseMessaging.instance.getInitialMessage();
    if (initialMessage != null) {
      // Handle navigation or actions
      final notificationData = {
        'title': initialMessage.notification?.title,
        'body': initialMessage.notification?.body,
        'data': initialMessage.data,
      };
      var willHandleNotification = await _genuinSdkPlugin
          .willHandleBackgroundNotifications(notificationData);
      if (willHandleNotification == true) {
        _genuinSdkPlugin.handleBackgroundNotifications(notificationData);
      } else {
        // Your notification handling
      }
    }

    // This method will be called when app is in foreground and push received
    FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
      if (kDebugMode) {
        print('Handling a foreground message: ${message.messageId}');
        print('Message data: ${message.data}');
        print('Message notification: ${message.notification?.title}');
        print('Message notification: ${message.notification?.body}');
      }

      final notificationData = {
        'title': message.notification?.title,
        'body': message.notification?.body,
        'data': message.data,
        'icon': 'mipmap/ic_notification'
        // OR 'icon':'drawable/ic_notification'[if image put under drawable folder]
      };
      var willHandleNotification = await _genuinSdkPlugin
          .willHandleForegroundNotifications(notificationData);
      if (willHandleNotification == true) {
        _genuinSdkPlugin.handleForegroundNotifications(notificationData);
      } else {
        // Your notification handling
      }
    });

    FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

    //This method will be called when user clicked on notification[Push notification is received when app is in background/killed]
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
      final notificationData = {
        'title': message.notification?.title,
        'body': message.notification?.body,
        'data': message.data,
      };
      var willHandleNotification = await _genuinSdkPlugin
          .willHandleBackgroundNotifications(notificationData);
      if (willHandleNotification == true) {
        _genuinSdkPlugin.handleBackgroundNotifications(notificationData);
      } else {
        // Your notification handling
      }
    });

    runApp(const MyApp());
  }

  ```
</CodeGroup>

**5. Handle SSO Login Explicitly in SDK**

To Auto Login in the SDK, You need to call below method, whenever user is log in to your application.

<Note>
  **Note**: You don’t need to call the below method if you have implemented the Embed With SSO already.
</Note>

<CodeGroup>
  ```

  import 'package:genuin_sdk/genuin_sdk.dart';

  final _genuinSdkPlugin = GenuinSdk();
  await _genuinSdkPlugin.ssoLogin("YOUR_SSO_TOKEN");

  ```
</CodeGroup>

**6. Handle SSO Logout in SDK**

<CodeGroup>
  ```

  import 'package:genuin_sdk/genuin_sdk.dart';

  final _genuinSdkPlugin = GenuinSdk();
  await _genuinSdkPlugin.ssoLogout();

  ```
</CodeGroup>

## Support

For further assistance with integrating the `genuin-react-native` SDK, please contact the Genuin support team or refer to the official documentation. The Genuin team is available to help you with any issues or questions you might have during the integration process.
