Skip to content
Open
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
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,36 @@ It seems that Expo introduced some breaking changes in SDK 33, so if you are usi

Your React Native app's screen resolution, app name, app ID, app version and multiple other parameters will be automatically resolved and sent with each hit or event.

##### Hits
For SDK 44+ support you will need to provide the `clientId` in the form a UUID as `Constants.installationId` has been deprecated. You should generate and store this where appropriate for the platform and provide the value as the second argument.

##### Hits

Sending page hits or screen hits is done by constructing a new `PageHit` or `ScreenHit` instance and passing it to the `hit` function of an `Analytics` instance.

```
import { Analytics, PageHit } from 'expo-analytics';

const analytics = new Analytics('UA-XXXXXX-Y');
const analytics = new Analytics('UA-XXXXXX-Y', 'UUID');
analytics.hit(new PageHit('Home'))
.then(() => console.log("success"))
.catch(e => console.log(e.message));
```

##### Events

You can also send custom events by constructing a new `Event` instance and passing it to the `event` function. Events have four parameters.
You can also send custom events by constructing a new `Event` instance and passing it to the `event` function. Events have four parameters.

* Event Category
* Event Action
* Event Label (optional, but recommended)
* Event Value (optional, integer)

These parameters are passed to the `Event` constructor in that order.
These parameters are passed to the `Event` constructor in that order.

```
import { Analytics, Event } from 'expo-analytics';

const analytics = new Analytics('UA-XXXXXX-Y');
const analytics = new Analytics('UA-XXXXXX-Y', 'UUID');
analytics.event(new Event('Video', 'Play', 'The Big Lebowski', 123))
.then(() => console.log("success"))
.catch(e => console.log(e.message));
Expand All @@ -66,7 +68,7 @@ analytics.event(new Event('Video', 'Play', 'The Big Lebowski', 123))
```
import { Analytics, Event } from 'expo-analytics';

const analytics = new Analytics('UA-XXXXXX-Y');
const analytics = new Analytics('UA-XXXXXX-Y', 'UUID');
analytics.addCustomDimension(1, 'TrialAccount');
analytics.addCustomDimension(2, 'Comedy');
analytics.event(new Event('Video', 'Play', 'The Big Lebowski', 123))
Expand All @@ -87,7 +89,7 @@ analytics.removeCustomDimension(1);
```
import { Analytics, Event } from 'expo-analytics';

const analytics = new Analytics('UA-XXXXXX-Y');
const analytics = new Analytics('UA-XXXXXX-Y', 'UUID');
analytics.addCustomMetric(1, 15);
analytics.removeCustomMetric(1);
```
Expand All @@ -100,12 +102,12 @@ You can also optionally include any additional [supported parameters](https://de
import { Analytics } from 'expo-analytics';

// pass in the user ID (uid), referrer (dr) and campaign name (cn)
const analytics = new Analytics('UA-XXXXXX-Y', { uid: '999', dr: 'github.com', cn: 'get_more_views' });
const analytics = new Analytics('UA-XXXXXX-Y', 'UUID', { uid: '999', dr: 'github.com', cn: 'get_more_views' });
```

##### Ecommerce tracking
##### Ecommerce tracking
###### Transaction hit type
You can also send purchase by constructing a new `Transaction` instance and passing it to the `transaction` function. Transaction have five parameters.
You can also send purchase by constructing a new `Transaction` instance and passing it to the `transaction` function. Transaction have five parameters.

* id (Required, string)
* affiliation (Optional, string)
Expand All @@ -118,15 +120,15 @@ These parameters are passed to the `Transaction` constructor in that order.
```
import { Analytics, Transaction } from 'expo-analytics';

const analytics = new Analytics('UA-XXXXXX-Y');
const analytics = new Analytics('UA-XXXXXX-Y', 'UUID');

analytics.hit(new Transaction('1235', 'Store', 38.43, 1.29, 5))
.then(() => console.log("success"))
.catch(e => console.log(e.message));
```

###### Item hit type
You can also send along the purchase the products that were purchased in the transaction, constructing a new `AddItem` instance and passing it to the `AddItem` function. 'AddItem' have six parameters.
You can also send along the purchase the products that were purchased in the transaction, constructing a new `AddItem` instance and passing it to the `AddItem` function. 'AddItem' have six parameters.

* id (The transaction id, Required, string)
* name (Required, string)
Expand All @@ -140,7 +142,7 @@ These parameters are passed to the `AddItem` constructor in that order.
```
import { Analytics, AddItem } from 'expo-analytics';

const analytics = new Analytics('UA-XXXXXX-Y');
const analytics = new Analytics('UA-XXXXXX-Y', 'UUID');

analytics.hit(new AddItem('1235', 'T-SHIRT', 11.99, 1, 'DD44', 'Clothes'))
.then(() => console.log("success"))
Expand All @@ -154,7 +156,7 @@ The Google Analytics API is a bit particular. If you're not seeing Real Time hi
```
import { Analytics, PageHit } from 'expo-analytics';

const analytics = new Analytics('UA-XXXXXX-Y', null, { debug: true });
const analytics = new Analytics('UA-XXXXXX-Y', 'UUID', null, { debug: true });
analytics.hit(new PageHit('IsItWorking'))
.then(() => console.log("success"))
.catch(e => console.log(e.message));
Expand Down Expand Up @@ -184,7 +186,7 @@ const analytics = new Analytics('UA-XXXXXX-Y', null, { userAgent: 'Custom UserAg

* 1.0.9 Support for Expo 0.33. Thanks, @rossb89.

* 1.0.8 Adding TypeScript definitions.
* 1.0.8 Adding TypeScript definitions.

* 1.0.7 Promisification. Thanks, @dylancompanjen!

Expand Down
54 changes: 32 additions & 22 deletions analytics.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Platform, Dimensions } from 'react-native';
import {Platform, Dimensions} from 'react-native';
import Constants from 'expo-constants';
import * as Application from 'expo-application';

import { ScreenHit, PageHit, Event, Serializable } from './hits';
import {Serializable} from './hits';

const { width, height } = Dimensions.get('window');
const {width, height} = Dimensions.get('window');

let defaultOptions = { debug: false };
let defaultOptions = {debug: false};

let webViewUserAgent = null;
const getWebViewUserAgent = async (options) => {
Expand All @@ -16,67 +17,76 @@ const getWebViewUserAgent = async (options) => {
}
if (webViewUserAgent) return resolve(webViewUserAgent);
Constants.getWebViewUserAgentAsync()
.then(userAgent => {
webViewUserAgent = userAgent;
resolve(userAgent);
})
.catch(() => resolve('unknown user agent'))
.then(userAgent => {
webViewUserAgent = userAgent;
resolve(userAgent);
})
.catch(() => resolve('unknown user agent'))
});
}

export default class Analytics {
customDimensions = []
customMetrics = []

constructor(propertyId, additionalParameters = {}, options = defaultOptions){
constructor(propertyId, clientId, additionalParameters = {}, options = defaultOptions) {
this.propertyId = propertyId;
this.options = options;
this.clientId = Constants.installationId;
this.clientId = clientId;
let {an, aid, av} = additionalParameters

if (Application.applicationName && Application.applicationId && Application.nativeApplicationVersion) {
an = an ? an : Application.applicationName
aid = aid ? aid : Application.applicationId
av = av ? av : Application.nativeApplicationVersion
} else if (!an || !aid || !av) {
console.warn(`It looks like you're in the bare workflow and haven't supplied 'an', 'aid' or 'av' as additional parameters.`)
}
this.parameters = {
an: Constants.manifest.name,
aid: Constants.manifest.slug,
av: Constants.manifest.version,
an,
aid,
av,
sr: `${width}x${height}`,
...additionalParameters
};

this.promiseGetWebViewUserAgentAsync = getWebViewUserAgent(options)
.then(userAgent => {
this.userAgent = userAgent;
if(this.options.debug){
if (this.options.debug) {
console.log(`[expo-analytics] UserAgent=${userAgent}`);
console.log(`[expo-analytics] Additional parameters=`, this.parameters);
}
});
}

hit(hit){
hit(hit) {
// send only after the user agent is saved
return this.promiseGetWebViewUserAgentAsync
.then(() => this.send(hit));
}

event(event){
event(event) {
// send only after the user agent is saved
return this.promiseGetWebViewUserAgentAsync
.then(() => this.send(event));
}

addParameter(name, value){
addParameter(name, value) {
this.parameters[name] = value;
}

addCustomDimension(index, value){
addCustomDimension(index, value) {
this.customDimensions[index] = value;
}

removeCustomDimension(index){
removeCustomDimension(index) {
delete this.customDimensions[index];
}

addCustomMetric(index, value) {
this.customMetrics[index] = value;
}
}

removeCustomMetric(index) {
delete this.customMetrics[index];
Expand Down Expand Up @@ -135,7 +145,7 @@ export default class Analytics {
options.mode = 'no-cors';
}

if(this.options.debug){
if (this.options.debug) {
console.log(`[expo-analytics] Sending GET request to ${url}`);
}

Expand Down
6 changes: 3 additions & 3 deletions hits.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export class Serializable {
}

toQueryString() {
var str = [];
var obj = this.toObject();
for (var p in obj) {
const str = [];
const obj = this.toObject();
for (const p in obj) {
if (obj.hasOwnProperty(p) && obj[p]) {
str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
}
Expand Down
Loading