Skip to content

Repository files navigation

Netmera React Native Expo Example

NETMERA is a Mobile Application Engagement Platform. We offer a series of development tools and app communication features to help your mobile business ignite and soar.

Installation

$ npm install react-native-netmera --save

Expo Prebuild Installation

In order to perform Native integrations, you must first expose the project's Native modules. To do this, you must run the npx expo prebuild command. If your project's native modules (android and ios folders) are exposed, you do not need to run this command.

Handling the Absence of index.js in New Versions of Expo

The new versions of Expo do not include the index.js file. Instead, it comes as expo-router/entry.js file inside the Node Modules folder. To extract this file, you should change the "main": "expo-router/entry" field in the package.json file to "main": "entry.js". Then you can create entry.js file in your root directory.

Setup - Android Part

  1. Create and register your app in Firebase console.

  2. Download google-services.json file and place it into android/app/ folder.

  3. In your project's build gradle file, add the following dependencies.

buildscript {
    repositories {
        google()
        mavenCentral()
        maven {url 'https://developer.huawei.com/repo/'}
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:8.0.2'
        classpath 'com.google.gms:google-services:4.3.15'
        classpath 'com.huawei.agconnect:agcp:1.6.3.300'
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://developer.huawei.com/repo/'}
        maven { url "https://release.netmera.com/release/android" }
    }
}
  1. In your app's build gradle file, add the following dependency.
 dependencies {

     implementation 'androidx.core:core:1.9.0'

 }
  1. Add the following into the top of app's build.gradle file.
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.huawei.agconnect'
  1. Initialize Netmera SDK in your MainApplication class, as shown below.
class MainApplication : Application(), ReactApplication {

  // ...

  override fun onCreate() {
    super.onCreate()
    // ...

    val netmeraConfiguration = RNNetmeraConfiguration.Builder()
        .firebaseSenderId(<YOUR GCM SENDER ID>)
        .huaweiSenderId(<YOUR HMS SENDER ID>)
        .apiKey(<YOUR NETMERA API KEY>)
        .logging(true) // This is for enabling Netmera logs.
        .build(this)
    RNNetmera.initNetmera(netmeraConfiguration)
  }
}

Setup - iOS Part

  1. Add the following pre_install and post_install blocks to your Podfile, and make sure use_frameworks! :linkage => :static is enabled for the target. This project's AppDelegate.swift does import Expo, which is only resolvable as a Swift module when the target actually links frameworks; Netmera/Swinject must in turn stay dynamic frameworks even under static-frameworks linkage, otherwise the app aborts at launch with Library not loaded: Swinject.
target 'YourApp' do
  use_expo_modules!

  # AppDelegate.swift does `import Expo`; Expo's podspec sets `static_framework = true`
  # but that only takes effect when the target actually links frameworks.
  use_frameworks! :linkage => :static

  # Netmera 2.x: Netmera/Swinject must stay dynamic frameworks even under static
  # frameworks linkage, otherwise Swinject.framework isn't copied into the app
  # bundle and the app aborts at launch with "Library not loaded: Swinject".
  pre_install do |installer|
    installer.pod_targets.each do |pod|
      if pod.name.start_with?('Netmera') || pod.name.include?('Swinject')
        def pod.build_type
          Pod::BuildType.dynamic_framework
        end
      end
    end
  end

  # ...

  post_install do |installer|
    # ...

    # Netmera 2.x: Swinject needs to be built for distribution to work with static libraries.
    installer.pods_project.targets.each do |target|
      if target.name.include?('Swinject')
        target.build_configurations.each do |config|
          config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
        end
      end
    end
  end
end

If your app's Info.plist only defines EXPO_CONFIGURATION_DEBUG (not the plain DEBUG Swift compilation condition — check OTHER_SWIFT_FLAGS in your target's Debug build settings), make sure any #if DEBUG block you write in Swift uses #if EXPO_CONFIGURATION_DEBUG instead, otherwise it will never evaluate to true and Metro's bundle URL won't resolve.

  1. Navigate to ios folder in your terminal and run the following command.
$ pod install
  1. Enable push notifications for your project

    1. If you have not generated a valid push notification certificate yet, generate one and then export by following the steps explained in Configuring Push Notifications section of App Distribution Guide
    2. Export the generated push certificate in .p12 format and upload to Netmera Dashboard.
    3. Enable Push Notifications capability for your application as explained in Enable Push Notifications guide.
    4. Enable Remote notifications background mode for your application as explained in Configuring Background Modes guide.
  2. Add the Netmera-Config.plist file to your ios/YOUR-APP directory (and add it to your app target's membership in Xcode).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>sdk_params</key>
        <dict>
            <key>api_key</key>
            <string>YOUR-API-KEY</string>
        </dict>
    </dict>
</plist>
  • If you are using Netmera on-premises, you must add your server URL as the base_url key inside sdk_params.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>sdk_params</key>
        <dict>
            ...
            <key>base_url</key>
            <string>YOUR-BASE-URL</string>
        </dict>
    </dict>
</plist>
  1. Shape your ios/YOUR-APP/AppDelegate.swift as following.
import Expo
import React
import NetmeraNotification
import RNNetmera

@main
class AppDelegate: EXAppDelegateWrapper, UNUserNotificationCenterDelegate {

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

    UNUserNotificationCenter.current().delegate = self

    // Init Netmera
    RNNetmera.initNetmera()
    Netmera.setPushDelegate(self)

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  // ...
}

// In order to use the widget URL callback, conform to NetmeraPushDelegate.
extension AppDelegate: NetmeraPushDelegate {
  func urlOpeningDecision(for url: URL, push: NetmeraBasePush) -> PushDelegateDecision {
    return .sdkHandles
  }

  func openURL(_ url: URL, for push: NetmeraBasePush) {
    RNNetmeraRCTEventEmitter.openURL(url, forPushObject: push)
  }
}
  1. In order to use iOS10 Media Push, follow the instructions in Netmera Product Hub. Differently, you should add the pods to the top of the Podfile as below.

    // For receiving Media Push, you must add Netmera pods to top of your Podfile.
    pod 'NetmeraNotificationServiceExtension', "4.23.1"
    pod "NetmeraNotificationContentExtension", "4.23.1"
    

Setup - React Native Part

  1. Create a new NetmeraPushHeadlessTask.ts inside your React Native project.
import type {
  NetmeraPushObject,
  NetmeraInteractiveAction,
  NetmeraCarouselObject,
} from 'react-native-netmera';

export const onPushRegister = async (data: { pushToken: string }) => {
  console.log('onPushRegister: ', data);
};

export const onPushReceive = async (push: NetmeraPushObject) => {
  console.log('onPushReceive: ', push);
};

export const onPushOpen = async (push: NetmeraPushObject) => {
  console.log('onPushOpen: ', push);
};

export const onPushDismiss = async (push: NetmeraPushObject) => {
  console.log('onPushDismiss: ', push);
};

export const onPushButtonClicked = async (
  push: NetmeraPushObject,
  action?: NetmeraInteractiveAction
) => {
  console.log('onPushButtonClicked: ', push);
  console.log('Clicked action: ', action);
};

export const onCarouselObjectSelected = async (
  push: NetmeraPushObject,
  carouselItem?: NetmeraCarouselObject
) => {
  console.log('onCarouselObjectSelected: ', push);
  console.log('Selected carousel item: ', carouselItem);
};
  1. Register push lifecycle callbacks inside your entry.js file (this project's Expo Router entry point — see the note about entry.js at the top of this README).
import { Netmera } from 'react-native-netmera';
import {
  onCarouselObjectSelected,
  onPushButtonClicked,
  onPushDismiss,
  onPushOpen,
  onPushReceive,
  onPushRegister,
} from './NetmeraPushHeadlessTask';

Netmera.setPushLifecycleCallbacks(
  onPushRegister,
  onPushReceive,
  onPushOpen,
  onPushDismiss,
  onPushButtonClicked,
  onCarouselObjectSelected
);

// This should be called after Netmera.setPushLifecycleCallbacks.
renderRootComponent(App);
  1. If you have custom Firebase Messaging integration, please see usage below.

1- Add the following line to your AndroidManifest.xml file inside the application tag to remove Netmera's default FCM service

<service
    android:name="com.netmera.nmfcm.NMFirebaseService"
    tools:node="remove" />

2- Update FirebaseMessaging methods like below

messaging()
   .getToken(firebase.app().options.messagingSenderId)
   .then(pushToken => {
       Netmera.onNetmeraNewToken(pushToken)
});

messaging().onMessage(async remoteMessage => {
   if (Netmera.isNetmeraRemoteMessage(remoteMessage.data)) {
       Netmera.onNetmeraFirebasePushMessageReceived(remoteMessage.from, remoteMessage.data)
   }
});

messaging().setBackgroundMessageHandler(async (remoteMessage) => {
    if (Netmera.isNetmeraRemoteMessage(remoteMessage.data)) {
        Netmera.onNetmeraFirebasePushMessageReceived(remoteMessage.from, remoteMessage.data)
    }
});

  1. If you have custom Huawei Messaging integration, please see usage below.

1- Add the following line to your AndroidManifest.xml file inside the application tag to remove Netmera's default HMS service

<service
   android:name="com.netmera.nmhms.NMHuaweiService"
   tools:node="remove" />

2- Update HuaweiPushKit methods like below

HmsPushInstanceId.getToken("")
   .then((result) => {
       Netmera.onNetmeraNewToken(result.result)
   })

HmsPushEvent.onRemoteMessageReceived((event) => {
  const remoteMessage = new RNRemoteMessage(event.msg);
  let data = JSON.parse(remoteMessage.getData());
  if (Netmera.isNetmeraRemoteMessage(data)) {
    Netmera.onNetmeraHuaweiPushMessageReceived(
      remoteMessage.getFrom(),
      data,
    );
  }
});

HmsPushMessaging.setBackgroundMessageHandler(async dataMessage => {
  const remoteMessage = new RNRemoteMessage(dataMessage);
  let data = JSON.parse(remoteMessage.getData());
  if (Netmera.isNetmeraRemoteMessage(data)) {
    Netmera.onNetmeraHuaweiPushMessageReceived(
        remoteMessage.getFrom(),
        data,
    );
  }
});

Calling React Native methods

Identify User Example
const identifyUser = () => {
    const user = new NetmeraUser();
    user.userId = <userId>;
    user.email = <email>;
    user.msisdn = <msisdn>;
    user.wpNumber = <whatsappNumber>;

    // Identify user with callback
    Netmera.identifyUser(user, (success, error) => {
      if (success) {
        console.log("User identified successfully")
      } else {
        console.error(error?.message)
      }
    });

    // Identify user without callback
    Netmera.identifyUser(user);
}
Update User Profile Example
const sendUserProfileUpdate = () => {
  const userProfile = new NetmeraUserProfile();
  userProfile.name.set('John');
  userProfile.surname.set('Doe');
  userProfile.dateOfBirth.set(new Date().getTime());
  userProfile.gender.set(Gender.MALE);
  userProfile.externalSegments.set(['segment1', 'segment2']);

  // Update user profile with callback
  Netmera.updateUserProfile(userProfile, (success, error) => {
      if (success) {
          ...
        } else {
          ...
        }
  });

  // Update user profile without callback
  Netmera.updateUserProfile(userProfile);
};

Note: updateUser() / updateUserAsync() from 1.x are removed in 2.x — they're replaced by the identifyUser() (id/email/msisdn/wpNumber) and updateUserProfile() (name/surname/gender/segments/custom attributes) pair above. See app/User.tsx and app/Profile.tsx, and the custom profile model src/models/MyNetmeraUserProfile.ts, in this example project.

Sending Event Examples

You can send your events as follows. For more examples, please see the Events screen in this example project.

  const sendLoginEvent = () => {
    const loginEvent = new NetmeraEventLogin();
    loginEvent.setUserId(<userId>);
    Netmera.sendEvent(loginEvent)
  }

  const sendRegisterEvent = () => {
    const registerEvent = new NetmeraEventRegister();
    registerEvent.setUserId(<userId>);
    Netmera.sendEvent(registerEvent)
  }

  const sendViewCartEvent = () => {
    const viewCartEvent = new NetmeraEventCartView();
    viewCartEvent.setSubTotal(<subTotal>);
    viewCartEvent.setItemCount(<itemCount>);
    Netmera.sendEvent(viewCartEvent)
  }

Note: the built-in typed event classes above (NetmeraEventLogin, NetmeraEventRegister, NetmeraEventCartView, NetmeraEventPurchase, ...) replace the hand-rolled 1.x event classes. For a fully custom event with no built-in class, extend NetmeraEvent (or an existing typed event, like NetmeraEventPurchase) and add your own setters — see src/models/Events.tsx — then call Netmera.sendEvent(event) as usual, or Netmera.sendGenericEvent(code, attributes) if you'd rather not define a class at all.

Deeplink

In order to manage your deeplinks, use the following method for iOS initial url's

Netmera.getInitialURL().then(url => {
   if (url) {
     console.log(url);
   }
 });

You can use Linking methods as before

Widget URL Callback

In order to use the widget URL callback, use onWidgetUrlTriggered method as follows.

 Netmera.onWidgetUrlTriggered(url => {
   console.log('Netmera triggered widget url: ', url);
 });
Push Notification Permissions

If you don't request notification permission at runtime, you can request it by calling the requestPushNotificationAuthorization() method. Note: Notification runtime permissions are required on Android 13 (API 33) or higher. Therefore, before calling the method, make sure your project targets an API of 33 and above.

  Netmera.requestPushNotificationAuthorization()
  .then((isGranted) => {
    ...
  });

You can call the checkNotificationPermission() method if you need to know the status of permissions.

 Netmera.checkNotificationPermission().then(status => {
   //NotificationPermissionStatus.NotDetermined
   //NotificationPermissionStatus.Blocked
   //NotificationPermissionStatus.Denied
   //NotificationPermissionStatus.Granted
 });
Netmera Inbox Examples

You can fetch the Netmera inbox as following. For more detailed usage, please see the PushInbox screen in this example project.

 const fetchInbox = async () => {
     try {
         const netmeraInboxFilter = new NetmeraInboxFilter();
         netmeraInboxFilter.status = Netmera.PUSH_OBJECT_STATUS_UNREAD;
         netmeraInboxFilter.pageSize = 2; // Fetch two push object
         const inbox = await Netmera.fetchInbox(netmeraInboxFilter);
         console.log("inbox", inbox);
     } catch (e) {
         console.log("error", e)
     }
 }

Note: fetchInbox() / fetchNextPage() now resolve to NetmeraPushObject[] directly — the 1.x NetmeraPushInbox type is removed.

Netmera Inbox Category Examples

You can fetch the Netmera category as following. For more detailed usage, please see the Category screen in this example project.

 const fetchCategory = async () => {
     try {
         const netmeraCategoryFilter = new NetmeraCategoryFilter()
         netmeraCategoryFilter.status = categoryState
         netmeraCategoryFilter.pageSize = 1 // Fetch one by one
         const categories = await Netmera.fetchCategory(netmeraCategoryFilter)
         console.log("categories", categories);
         setCategories(categories)
     } catch (e) {
         console.log("error", e)
     }
 };
Netmera Getting ExternalId (if exists before)
    Netmera.currentExternalId()
Netmera Popup Presentation

To enable popup presentation, you need to call the enablePopupPresentation() method on the page where you want to display the popup. Note: To show popup on the app start or everywhere in the app, please add this to entry.js file.

 Netmera.enablePopupPresentation();
Data Start-Stop Transfer
Stop Data Transfer Method

The stopDataTransfer() method is a useful feature that can help users to temporarily pause all requests sent by the SDK to the backend. This can be useful if, for example, the user needs to temporarily halt data transfers due to network issues or other reasons. Once the issue has been resolved, the user can then restart the data transfer using the startDataTransfer() method.

 Netmera.stopDataTransfer();
Start Data Transfer Method

The startDataTransfer() method is a complementary feature to the stopDataTransfer() method, which allows users to restart any stopped requests. This can be useful when the user has temporarily paused data transfers and is now ready to resume the transfer. Once the user calls the startDataTransfer() method, the SDK will attempt to resend any requests that were previously stopped.

 Netmera.startDataTransfer();

Please explore the source code of this example project (screens) and src/models (custom models) for detailed information.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages