Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Readme proofreading/formatting #119

Merged
merged 1 commit into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 92 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,17 @@ so you can import Android Klaviyo SDK references from your Kotlin/Java files wit

#### React Native 0.73.x

There are no additional installation requirements. Android support is fully tested and verified,
including `minSdkVersion=23`.
There are no additional installation requirements. Android support is fully tested and verified.

#### React Native 0.68.x - 0.72.x

We have successfully compiled the Klaviyo React Native SDK in a bare React Native template app for these versions
with the following modifications to the `android/build.gradle` file:

- Set `compileSdkVersion=34`
- Set `minSdkVersion=23`
- Set `compileSdkVersion=34`

See [Android Troubleshooting](Troubleshooting.md#android-troubleshooting) for possible exceptions.

#### React Native <= 0.67.x

Expand All @@ -136,20 +137,21 @@ pod install
The SDK must be initialized with the short alphanumeric [public API key](https://help.klaviyo.com/hc/en-us/articles/115005062267#difference-between-public-and-private-api-keys1)
for your Klaviyo account, also known as your Site ID.

Initialize _must_ be called prior to invoking any other SDK methods so that Klaviyo SDK can track profiles, events and push tokens toward the correct Klaviyo account.
Any SDK operations invoked before initialize will be dropped, and result in a logged error.
Initialize _must_ be called prior to invoking any other SDK methods so that Klaviyo SDK can track profiles, events and
push tokens toward the correct Klaviyo account. Any SDK operations invoked before initialize will be dropped,
and result in a logged error.

You can call `initialize` from your app's React Native layer or from the platform-specific native code.
This decision is dependent on your app's architecture. It is not required to initialize the SDK in both places!
Note: It is safe to re-initialize, e.g. if your app needs to connect to more than one Klaviyo account.
Note: It is safe to re-initialize, e.g. if your app needs to switch between more than one Klaviyo account.

### React Native Initialization

Below is an example of how to initialize the SDK from your React Native code:

```typescript
import { Klaviyo } from 'klaviyo-react-native-sdk';
Klaviyo.initialize('YOUR_KLAVIYO_PUBLIC_API_KEY');
Klaviyo.initialize('YOUR_PUBLIC_KLAVIYO_API_KEY');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the smallest nitpick, but this is the value we used in the code.

```

### Native Initialization
Expand Down Expand Up @@ -277,58 +279,56 @@ Refer to the following README sections on push setup:

### Collecting Push Tokens

Push tokens can be collected either from your app's react native code or in the native code. Below sections discuss both approaches, and
you are free to pick one that best suits your app's architecture. Note that doing this in one location is sufficient.
Push tokens can be collected either from your app's react native code or in the native code.
Below sections discuss both approaches, and you are free to pick one that best suits your app's architecture.
Note that doing this in one location is sufficient.

#### React Native Token Collection

In order to collect the APNs push token in your React Native code you need to:

1. Import a library such as [`@react-native-firebase/messaging`](https://www.npmjs.com/package/@react-native-firebase/messaging) to your react native project. The below instructions are specific for `@react-native-firebase/messaging` library.
2. Import Firebase iOS SDK to your iOS project. Setup instructions can be found [here](https://firebase.google.com/docs/ios/setup).
3. In order for the `UNUserNotificationCenter` delegate methods to be called in `AppDelegate`, method swizzling should be disabled for the Firebase SDK. For more information on this,
please refer to the [Firebase documentation](https://firebase.google.com/docs/cloud-messaging/ios/client). Disabling method swizzling be done by adding the following to your `Info.plist`:

```xml
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
```

1. Import a library such as [`@react-native-firebase/messaging`](https://www.npmjs.com/package/@react-native-firebase/messaging)
to your react native project. The below instructions are specific for `@react-native-firebase/messaging` library.
2. Import Firebase iOS SDK to your iOS project. Setup instructions can be found [here](https://firebase.google.com/docs/ios/setup).
3. In order for the `UNUserNotificationCenter` delegate methods to be called in `AppDelegate`, method swizzling must be
disabled for the Firebase SDK. For more information on this, please refer to the [Firebase documentation](https://firebase.google.com/docs/cloud-messaging/ios/client).
Disable method swizzling by adding the following to your `Info.plist`:
```xml
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
```
4. In `application:didRegisterForRemoteNotificationsWithDeviceToken:` method in your `AppDelegate.m` file, you can add the following code to set the push token to the firebase SDK:

```objective-c
// since we disbaled swizzling, we have to manually set this
FIRMessaging.messaging.APNSToken = deviceToken;
```

```objective-c
// since we disbaled swizzling, we have to manually set this
FIRMessaging.messaging.APNSToken = deviceToken;
```
5. Finally, in your React Native code, you can collect & set the push token as follows:

```typescript
import messaging from '@react-native-firebase/messaging';
import { Klaviyo } from 'klaviyo-react-native-sdk';
import { Platform } from 'react-native';

const fetchAndSetPushToken = async () => {
try {
let deviceToken: string | null = null;
if (Platform.OS === 'android') {
deviceToken = await messaging().getToken();
console.log('FCM Token:', deviceToken);
} else {
deviceToken = await messaging().getAPNSToken();
console.log('APNs Token:', deviceToken);
}

if (deviceToken != null && deviceToken.length > 0) {
Klaviyo.setPushToken(deviceToken!);
}
} catch (error) {
console.error('Error in fetchAndSetPushToken:', error);
}
};
```

For android token collection, there isn't any additional setup required on the native side. The above code should work as is.
```typescript
import messaging from '@react-native-firebase/messaging';
import { Klaviyo } from 'klaviyo-react-native-sdk';
import { Platform } from 'react-native';

const fetchAndSetPushToken = async () => {
try {
let deviceToken: string | null = null;
if (Platform.OS === 'android') {
deviceToken = await messaging().getToken();
console.log('FCM Token:', deviceToken);
} else {
deviceToken = await messaging().getAPNSToken();
console.log('APNs Token:', deviceToken);
}

if (deviceToken != null && deviceToken.length > 0) {
Klaviyo.setPushToken(deviceToken!);
}
} catch (error) {
console.error('Error in fetchAndSetPushToken:', error);
}
};
```

For Android token collection, there isn't any additional setup required on the native side. The above code should work as is.

#### Native Token Collection

Expand All @@ -339,49 +339,50 @@ Follow the platform-specific instructions below:

#### Notification Permission

Requesting user permission to display notifications can be managed in:

1. The native layer as instructed in our native SDK documentation,

- [Android](https://github.com/klaviyo/klaviyo-android-sdk#collecting-push-tokens)
- [iOS](https://github.com/klaviyo/klaviyo-swift-sdk?tab=readme-ov-file#request-push-notification-permission)

If you requested permission using native code then continue using Klaviyo's native platform SDKs `setToken` method to inform the SDK of permission change.
Requesting user permission to display notifications can be managed from the React Native code, or from platform-specific
native code. Note that either of these approaches is sufficient to inform the Klaviyo SDK of the permission change.

2. Leveraging a third party library that provides cross-platform permissions APIs like firebase [`react-native-firebase/messaging`](https://www.npmjs.com/package/@react-native-firebase/messaging). If you opt for a
cross-platform permission solution, you can now call the Klaviyo's react native SDK's `setToken` method to refresh the token's enablement status.
1. **React Native Notification Permission**:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured for consistency we should put react native section first

You can leverage a third party library that provides cross-platform permissions APIs like firebase [`react-native-firebase/messaging`](https://www.npmjs.com/package/@react-native-firebase/messaging).
If you opt for a cross-platform permission solution, call the Klaviyo React Native SDK's `setToken` method to refresh
the token's enablement status.

Below is an example of how to use `@react-native-firebase/messaging` to request permission and set the token:

```typescript
import messaging from '@react-native-firebase/messaging';

const requestUserPermission = async () => {
let isAuthorized = false;

if (Platform.OS === 'android') {
const androidAuthStatus = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
isAuthorized = androidAuthStatus === 'granted';
} else if (Platform.OS === 'ios') {
const iOsAuthStatus = await messaging().requestPermission();
isAuthorized =
iOsAuthStatus === messaging.AuthorizationStatus.AUTHORIZED ||
iOsAuthStatus === messaging.AuthorizationStatus.PROVISIONAL;
}

// refer the `fetchAndSetPushToken` method from the previous section for how to get and set the push token

if (isAuthorized) {
console.log('User has notification permissions enabled.');
} else {
console.log('User has notification permissions disabled');
}
};
```
```typescript
import messaging from '@react-native-firebase/messaging';

const requestUserPermission = async () => {
let isAuthorized = false;

if (Platform.OS === 'android') {
const androidAuthStatus = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
isAuthorized = androidAuthStatus === 'granted';
} else if (Platform.OS === 'ios') {
const iOsAuthStatus = await messaging().requestPermission();
isAuthorized =
iOsAuthStatus === messaging.AuthorizationStatus.AUTHORIZED ||
iOsAuthStatus === messaging.AuthorizationStatus.PROVISIONAL;
}

// refer the `fetchAndSetPushToken` method from the previous section for how to get and set the push token

if (isAuthorized) {
console.log('User has notification permissions enabled.');
} else {
console.log('User has notification permissions disabled');
}
};
```
2. **Native Notification Permission**:
Follow instructions from our native SDK documentation to request permission from native code:
- [Android](https://github.com/klaviyo/klaviyo-android-sdk#collecting-push-tokens)
- [iOS](https://github.com/klaviyo/klaviyo-swift-sdk?tab=readme-ov-file#request-push-notification-permission)

Note that either one of the above approaches is sufficient to inform the Klaviyo SDK of the permission change.
If you requested permission using native code then continue using Klaviyo's native platform SDKs `setToken`
method to inform the SDK of permission change.

### Receiving Push Notifications

Expand Down Expand Up @@ -444,7 +445,7 @@ Linking.getInitialURL().then((url) => {

## Troubleshooting

Use the [troubleshooting guide](Troubeshooting.md) to resolve common issues with the Klaviyo React Native SDK.
Use the [troubleshooting guide](Troubleshooting.md) to resolve common issues with the Klaviyo React Native SDK.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦🏽

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦🏽

If the issues you are facing isn't in the troubleshooting guide, and you believe it's a bug in the SDK, please file an issue in our repository.

## Contributing
Expand Down
25 changes: 15 additions & 10 deletions Troubeshooting.md → Troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

## Android Troubleshooting

1. We have seen projects, particularly on react-native versions `0.72.x` and `0.71.x`, that required a `minSdkVersion`
of `24`, despite the Klaviyo Android SDK supporting API 23+. If you encounter this, please file an issue in our
repository and provide version numbers of your react-native dependencies.
### `minSdkVersion` Issues
We have seen projects, particularly on react-native versions `0.72.x` and `0.71.x`, that required a `minSdkVersion`
of `24`, despite the Klaviyo Android SDK supporting API 23+. If you encounter this, please file an issue in our
repository and provide version numbers of your react-native dependencies.

## iOS Troubleshooting

### CocoaPods Installation Issues

1. If you are seeing issues related to `minimum deployment target` when installing pods, you may need to update your
minimum iOS version to 13.0 in your Podfile with one of the following strategies.
minimum iOS version to 13.0 in your Podfile with one of the following strategies:

- Specify iOS version directly in the `Podfile`:
```ruby
Expand All @@ -23,7 +24,6 @@
platform :ios, min_ios_version_supported
```
- Set the deployment target to 13.0 in XCode, and then pull `IPHONEOS_DEPLOYMENT_TARGET` from the XCode project:

```ruby
#######
# Read min iOS version from Xcode project and set as min iOS version for Podfile
Expand All @@ -37,12 +37,17 @@
platform :ios, min_ios_version_supported
```

2. If the command `pod install` is outputting version mismatch errors for `KlaviyoSwift`, please run `pod update KlaviyoSwift`
as indicated in the error message to update your local pods spec repo.
2. If the command `pod install` is outputting version mismatch errors for `KlaviyoSwift`, please
run `pod update KlaviyoSwift` as indicated in the error message to update your local pods spec repo.

### `UNUserNotificationCenter` delegate methods not being called

If you are not seeing the delegate methods for `UNUserNotificationCenter` being called in `AppDelegate`, there are two possible reasons for this,
If you are not seeing the delegate methods for `UNUserNotificationCenter` being called in `AppDelegate`,
there are two possible reasons for this:

1. [Notifee](https://notifee.app/) intercepts the AppDelegate delegate methods and hence you may not receive the delegate calls if notifee is included in the iOS project. The solution is to remove notifee dependency from your project or exclude it for iOS.
2. Firebase iOS SDK also swizzles AppDelegate methods when configured on your iOS app. If after disabling notifee, if the delegates are still not called, this may be the reason. Method swizzling can be turned off by following [Firebase's documentation](https://firebase.google.com/docs/cloud-messaging/ios/client).
1. [Notifee](https://notifee.app/) intercepts the AppDelegate delegate methods and hence you may not receive
the delegate calls if notifee is included in the iOS project. The solution is to remove notifee dependency
from your project or exclude it for iOS.
2. Firebase iOS SDK also swizzles AppDelegate methods when configured on your iOS app. If after disabling notifee,
if the delegates are still not called, this may be the reason. Method swizzling can be turned off by following
[Firebase's documentation](https://firebase.google.com/docs/cloud-messaging/ios/client).