Skip to main content

Multi-Platform Tracking

Most products live on more than one platform - a website, an iOS app, an Android app. In Joryio you model this with one app per platform, all feeding the same workspace: each platform gets its own SDK key and its own push credentials, while every event lands on one shared user profile.

One app per platform​

Create a separate app (under Settings → Apps) for each platform you ship on. You can create Web, iOS, and Android apps; e-commerce store apps (Shopify, WooCommerce, Magento) are created automatically when you connect those integrations.

Each app has its own SDK key in the format jry_sdk_<platform>_<random> - the platform is embedded in the key, so you can always tell at a glance which build a key belongs to:

jry_sdk_web_4f2a9c... Website
jry_sdk_ios_b81d3e... iOS app
jry_sdk_android_77c0aa... Android app

The key does three things: it authenticates SDK requests, it routes events to the right workspace, and it stamps every event with the app's identity ($app_id, $app_name, $platform) so you can segment and analyze per platform.

React Native apps​

There is no separate "React Native" platform. The React Native SDK bridges the native iOS and Android SDKs, so a React Native product uses two apps - one iOS and one Android - and passes the matching key at runtime:

import { Platform } from 'react-native';
import Joryio from '@joryio/react-native-sdk';

await Joryio.initialize(
Platform.OS === 'ios'
? 'jry_sdk_ios_YOUR_IOS_KEY'
: 'jry_sdk_android_YOUR_ANDROID_KEY',
'https://api-eu1.joryio.com/api',
);

This keeps push credentials correct per store build (APNS for the iOS app, FCM for the Android app) and keeps platform analytics accurate.

One user profile across platforms​

Apps separate where events come from; they do not separate who they belong to. All apps in a workspace share the same user base, and profiles are unified by user ID:

  • Call identify with the same stable user ID on every platform (your database user ID is the usual choice - never an email that can change).
  • Before login, each device tracks under its own anonymous ID. When the user identifies, that device's anonymous history is merged into the identified profile - so signup attribution from web and first-launch events from mobile all end up in one place.
  • Identify as early as possible in each session (at login, and on app start when a session is restored), so as few events as possible are recorded anonymously.
const joryio = new JoryioSDK({ sdkKey: 'jry_sdk_web_...' });

joryio.identify('user_123');

Once unified, the profile powers cross-platform behavior everywhere:

  • Segments can span platforms ("used iOS but never web") because every event carries $platform and $app_id.
  • Journeys treat the user as one person: an Order Completed event from the iOS app can satisfy the goal of a journey the user entered from the website.
  • Server-managed attributes such as sessionCount count activity across all devices and platforms.

Attributes set from any platform (setAttributes) write to the same profile - last write wins, so keep attribute names and types consistent across codebases.

Per-platform push credentials​

Push credentials live on the app, which is why one app per platform matters:

  • iOS app - upload your APNS auth key (.p8, with Team ID and Key ID) or certificate (.p12) in the app's push configuration.
  • Android app - upload your Firebase (FCM) service account JSON.
  • Web app - enable web push on the app; Joryio generates a VAPID keypair and exposes the public key to the Web SDK.

Configure these from Settings → Apps via the push configuration action on each app row. Secrets are encrypted at rest and shown masked after saving.

Which app receives a push?​

A push targets one app - the credentials of a single iOS or Android app decide which devices get the notification.

  • One app, or one per platform (e.g. one iOS + one Android): the right app is unambiguous, so Joryio resolves it automatically. You won't see an app picker.
  • Two or more apps on the same platform (e.g. two iOS builds): the choice is ambiguous, so a Target app picker appears - in the campaign composer and on the journey Push node - to choose which app the push goes out from. Leave it on Automatic to use the first available app.