Skip to content

Commit

Permalink
Merge pull request #527 from AppsFlyerSDK/releases/6.x.x/6.13.x/6.13.…
Browse files Browse the repository at this point in the history
…0-rc2

Releases/6.x.x/6.13.x/6.13.0 rc2
  • Loading branch information
amit-kremer93 authored Feb 19, 2024
2 parents fe3b80d + 2635e1d commit 3806778
Show file tree
Hide file tree
Showing 20 changed files with 365 additions and 28 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 6.13.0
Release date: *2024-02-19*

- Add DMA support
- Fix incompatible config for RN >= 0.69.x
- Update Plugin to v6.13.0

## 6.12.2
Release date: *2023-08-29*

Expand Down
47 changes: 47 additions & 0 deletions Docs/RN_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ The list of available methods for this plugin is described below.
- [addPushNotificationDeepLinkPath](#addpushnotificationdeeplinkpath)
- [appendParametersToDeepLinkingURL](#appendparameterstodeeplinkingurl)
- [disableAdvertisingIdentifier](#disableAdvertisingIdentifier)
- [enableTCFDataCollection](#enableTCFDataCollection)
- [setConsentData](#setConsentData)
- [Android Only APIs](#android-only-apis)
- [setCollectAndroidID](#setcollectandroidid)
- [setCollectIMEI](#setcollectimei)
Expand Down Expand Up @@ -750,6 +752,51 @@ Disables collection of various Advertising IDs by the SDK.<br>
appsFlyer.disableAdvertisingIdentifier(true);
```

---
### enableTCFDataCollection
`enableTCFDataCollection(enabled): void`

instruct the SDK to collect the TCF data from the device.


| parameter | type | description |
| ---------- |----------|------------------ |
| enabled | boolean | enable/disable TCF data collection |

*Example:*

```javascript
appsFlyer.enableTCFDataCollection(true);
```

---
### setConsentData
`setConsentData(consentObject): void`

When GDPR applies to the user and your app does not use a CMP compatible with TCF v2.2, use this API to provide the consent data directly to the SDK.<br>
The AppsFlyerConsent object has 2 methods:

1. `AppsFlyerConsent.forNonGDPRUser`: Indicates that GDPR doesn’t apply to the user and generates nonGDPR consent object. This method doesn’t accept any parameters.
2. `AppsFlyerConsent.forGDPRUser`: create an AppsFlyerConsent object with 2 parameters:


| parameter | type | description |
| ---------- |----------|------------------ |
| hasConsentForDataUsage | boolean | Indicates whether the user has consented to use their data for advertising purposes |
| hasConsentForAdsPersonalization | boolean | Indicates whether the user has consented to use their data for personalized advertising |

*Example:*

```javascript
import appsFlyer, {AppsFlyerConsent} from 'react-native-appsflyer';

let nonGDPRUser = AppsFlyerConsent.forNonGDPRUser();
// OR
let GDPRUser = AppsFlyerConsent.forGDPRUser(true, false);

appsFlyer.setConsentData(nonGDPRUser /**or**/ GDPRUser);
```

## Android Only APIs

### setCollectAndroidID
Expand Down
139 changes: 139 additions & 0 deletions Docs/RN_CMP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
title: Send consent for DMA compliance
category: 5f9705393c689a065c409b23
parentDoc: 645213236f53a00d4daa9230
order: 12
hidden: false
---

## Send consent for DMA compliance
The SDK offers two alternative methods for gathering consent data:

Through a Consent Management Platform (CMP): If the app uses a CMP that complies with the Transparency and Consent Framework (TCF) v2.2 protocol, the SDK can automatically retrieve the consent details.

OR

Through a dedicated SDK API: Developers can pass Google's required consent data directly to the SDK using a specific API designed for this purpose.

### Use CMP to collect consent data
A CMP compatible with TCF v2.2 collects DMA consent data and stores it in NSUserDefaults (iOS) and SharedPreferences (Android). To enable the SDK to access this data and include it with every event, follow these steps:

1. Call `appsFlyer.enableTCFDataCollection(true)`
2. Initialize the SDK in [manual start mode](/Docs/RN_API.md#initsdk)
3. Use the CMP to decide if you need the consent dialog in the current session to acquire the consent data. If you need the consent dialog move to step 4; otherwise move to step 5
4. Get confirmation from the CMP that the user has made their consent decision and the data is available in NSUserDefaults/SharedPreferences
5. Call `appsFlyer.startSdk()`
```javascript
useEffect(() => {
const option = {
isDebug: true,
devKey: 'UxXxXxXxXd',
onInstallConversionDataListener: true,
onDeepLinkListener: true,
timeToWaitForATTUserAuthorization: 10,
manualStart: true, // <-- Manual start
};
// TCF data collection
appsFlyer.enableTCFDataCollection(true);

//init appsflyer
appsFlyer.initSdk(
option,
res => {
console.log(res);
},
err => {
console.log(err);
},
);

...

// CMP Pseudocode
if (cmpManager.hasConsent()) {
appsFlyer.startSdk();
} else {
cmpManager.presentConsentDialog(res => {
appsFlyer.startSdk();
});
}
},[])
```
## Manually collect consent data
If your app does not use a CMP compatible with TCF v2.2, use the SDK API detailed below to provide the consent data directly to the SDK.

### When GDPR applies to the user
If GDPR applies to the user, perform the following:

1. Given that GDPR is applicable to the user, determine whether the consent data is already stored for this session.
1. If there is no consent data stored, show the consent dialog to capture the user consent decision.
2. If there is consent data stored continue to the next step.
2. To transfer the consent data to the SDK create an AppsFlyerConsent object using `forGDPRUser` method that accepts the following parameters:<br>
`hasConsentForDataUsage: boolean` - Indicates whether the user has consented to use their data for advertising purposes.<br>
`hasConsentForAdsPersonalization: boolean` - Indicates whether the user has consented to use their data for personalized advertising.
3. Call `appsFlyer.setConsentData(consentData)` with the AppsFlyerConsent object.
4. Call `appsFlyer.initSdk()`.
```javascript
import appsFlyer, {AppsFlyerConsent} from 'react-native-appsflyer';

useEffect(() => {
const option = {
isDebug: true,
devKey: 'UxXxXxXxXd',
onInstallConversionDataListener: true,
onDeepLinkListener: true,
timeToWaitForATTUserAuthorization: 10,
};

// user consent data
let consentData = AppsFlyerConsent.forGDPRUser(true, false);

appsFlyer.setConsentData(consentData);

//start appsflyer
appsFlyer.initSdk(
option,
res => {
console.log(res);
},
err => {
console.log(err);
},
);
},[])
```
### When GDPR does not apply to the user

If GDPR doesn’t apply to the user perform the following:
1. Create an AppsFlyerConsent object using `forNonGDPRUser` method that doesn't accepts any parameters
2. Call `appsFlyer.setConsentData(consentData)` with the AppsFlyerConsent object.
3. Call `appsFlyer.initSdk()`.
```javascript
import appsFlyer, {AppsFlyerConsent} from 'react-native-appsflyer';

useEffect(() => {
const option = {
isDebug: true,
devKey: 'UxXxXxXxXd',
onInstallConversionDataListener: true,
onDeepLinkListener: true,
timeToWaitForATTUserAuthorization: 10,
};

// GDPR does not apply to the user
let consentData = AppsFlyerConsent.forNonGDPRUser();

appsFlyer.setConsentData(consentData);

//start appsflyer
appsFlyer.initSdk(
option,
res => {
console.log(res);
},
err => {
console.log(err);
},
);
},[])
```
2 changes: 1 addition & 1 deletion Docs/RN_UserInvite.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The link that is generated for the user invite will use this OneLink ID as the b

```javascript

// set the tamplate ID before you generate a link. Without it UserInvite won't work.
// set the template ID before you generate a link. Without it UserInvite won't work.
appsFlyer.setAppInviteOneLinkID('scVs', null);

// set the user invite params
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
### <a id="plugin-build-for"> This plugin is built for

- Android AppsFlyer SDK **v6.12.2**
- iOS AppsFlyer SDK **v6.12.2**
- Android AppsFlyer SDK **v6.13.0**
- iOS AppsFlyer SDK **v6.13.0**

## <a id="breaking-changes"> ❗❗ Breaking changes when updating to v6.x.x❗❗

Expand Down Expand Up @@ -51,6 +51,7 @@ If you have used 1 of the removed APIs, please check the integration guide for t
- [Test integration](/Docs/RN_Testing.md)
- [In-app events](/Docs/RN_InAppEvents.md)
- [Uninstall measurement](/Docs/RN_UninstallMeasurement.md)
- [Send consent for DMA compliance](/Docs/RN_CMP.md)
## 🔗 Deep Linking
- [Integration](/Docs/RN_DeepLinkIntegrate.md)
- [***Expo*** Integration](/Docs/RN_ExpoDeepLinkIntegration.md)
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,5 @@ repositories {
dependencies {
implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
implementation "com.android.installreferrer:installreferrer:${safeExtGet('installReferrerVersion', '2.1')}"
api "com.appsflyer:af-android-sdk:${safeExtGet('appsflyerVersion', '6.12.2')}"
api "com.appsflyer:af-android-sdk:${safeExtGet('appsflyerVersion', '6.13.0')}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

public class RNAppsFlyerConstants {

final static String PLUGIN_VERSION = "6.12.2";
final static String PLUGIN_VERSION = "6.13.0";
final static String NO_DEVKEY_FOUND = "No 'devKey' found or its empty";
final static String UNKNOWN_ERROR = "AF Unknown Error";
final static String SUCCESS = "Success";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,27 @@ public void performOnDeepLinking() {
Log.d("AppsFlyer", "performOnDeepLinking: activity is null!");
}
}


@ReactMethod
public void enableTCFDataCollection(Boolean enabled) {
AppsFlyerLib.getInstance().enableTCFDataCollection(enabled);
}

@ReactMethod
public void setConsentData(ReadableMap consentData) {
JSONObject JSONConsentData = RNUtil.readableMapToJson(consentData);
boolean isUserSubjectToGDPR = JSONConsentData.optBoolean("isUserSubjectToGDPR");
boolean hasConsentForDataUsage = JSONConsentData.optBoolean("hasConsentForDataUsage");
boolean hasConsentForAdsPersonalization = JSONConsentData.optBoolean("hasConsentForAdsPersonalization");
AppsFlyerConsent consentObject;
if (isUserSubjectToGDPR) {
consentObject = AppsFlyerConsent.forGDPRUser(hasConsentForDataUsage, hasConsentForAdsPersonalization);
} else {
consentObject = AppsFlyerConsent.forNonGDPRUser();
}
AppsFlyerLib.getInstance().setConsentData(consentObject);
}

@ReactMethod
public void addListener(String eventName) {
// Keep: Required for RN built in Event Emitter Calls.
Expand Down
4 changes: 2 additions & 2 deletions demos/appsflyer-react-native-app/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ buildscript {
ext {
buildToolsVersion = "30.0.2"
minSdkVersion = 21
compileSdkVersion = 31
targetSdkVersion = 31
compileSdkVersion = 32
targetSdkVersion = 32
ndkVersion = "20.1.5948944"
}
repositories {
Expand Down
4 changes: 2 additions & 2 deletions demos/appsflyer-react-native-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"react-native-elements": "^3.4.2",
"react-native-gesture-handler": "^1.10.3",
"react-native-safe-area-context": "^3.3.2",
"react-native-screens": "^3.7.0",
"react-native-vector-icons": "^8.1.0"
"react-native-screens": "3.7.2",
"react-native-vector-icons": "8.1.0"
},
"devDependencies": {
"@babel/core": "^7.12.9",
Expand Down
9 changes: 9 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ declare module "react-native-appsflyer" {
brandDomain?: string;
}

export const AppsFlyerConsent: {
forGDPRUser: (hasConsentForDataUsage: boolean, hasConsentForAdsPersonalization: boolean) => void;
forNonGDPRUser: () => void;
}

export type AppsFlyerConsentType = typeof AppsFlyerConsent;

const appsFlyer: {
onInstallConversionData(callback: (data: ConversionData) => any): () => void;
onInstallConversionFailure(callback: (data: ConversionData) => any): () => void;
Expand Down Expand Up @@ -151,6 +158,8 @@ declare module "react-native-appsflyer" {
setPartnerData(partnerId: string, partnerData: object): void
appendParametersToDeepLinkingURL(contains: string, parameters: object): void
startSdk(): void
enableTCFDataCollection(enabled: boolean): void
setConsentData(consentData: AppsFlyerConsentType): void

/**
* For iOS Only
Expand Down
40 changes: 39 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -625,10 +625,48 @@ appsFlyer.performOnDeepLinking = () => {
return RNAppsFlyer.performOnDeepLinking();
};

/**
* instruct the SDK to collect the TCF data from the device.
* @param enabled: if the sdk should collect the TCF data. true/false
*/
appsFlyer.enableTCFDataCollection= (enabled) => {
return RNAppsFlyer.enableTCFDataCollection(enabled);
}

/**
* If your app does not use a CMP compatible with TCF v2.2, use the SDK API detailed below to provide the consent data directly to the SDK.
* @param consentData: AppsFlyerConsent object.
*/
appsFlyer.setConsentData = (consentData) => {
return RNAppsFlyer.setConsentData(consentData);
}

function AFParseJSONException(_message, _data) {
this.message = _message;
this.data = _data;
this.name = 'AFParseJSONException';
}

export default appsFlyer;
// Consent object
export const AppsFlyerConsent = (function () {
// Private constructor
function AppsFlyerConsent(isUserSubjectToGDPR, hasConsentForDataUsage, hasConsentForAdsPersonalization) {
this.isUserSubjectToGDPR = isUserSubjectToGDPR;
this.hasConsentForDataUsage = hasConsentForDataUsage;
this.hasConsentForAdsPersonalization = hasConsentForAdsPersonalization;
}

return {
// Factory method for GDPR user
forGDPRUser: function(hasConsentForDataUsage, hasConsentForAdsPersonalization) {
return new AppsFlyerConsent(true, hasConsentForDataUsage, hasConsentForAdsPersonalization);
},

// Factory method for non GDPR user
forNonGDPRUser: function() {
return new AppsFlyerConsent(false, null, null);
}
};
})();

export default appsFlyer;
Loading

0 comments on commit 3806778

Please sign in to comment.