Skip to content
Switch branches/tags
Go to file
2 contributors

Users who have contributed to this file

MMA (Mobile Marketing Automation)

Mozilla wants to engage with users more. MMA is the project for this purpose. When a user performs a certain UI action (or set of UI actions), she will see a prompt and have a chance to interact with it. For example, if a user uses Firefox 10 times a week, but Firefox is not her default browser, we'll prompt the user the next time when she launches our app, and guide her to set us as default browser.

Starting in Firefox 8.0 on iOS, Mozilla is using a third party framework called "Leanplum" in order to achieve this. Leanplum is a San Francisco company, founded in 2012. We put their SDK in our codebase via Carthage.

The SDK is documented at

There are three major component in Leanplum SDK.

  1. Events : Events are fired when users perform certain actions.
  2. User Attributes: User Attributes are set on a per-user basis, and inform us about an aspect of the user.
  3. Deep Links: Actions that users can perform to interact with the Message.
  4. Messages: User Interaction points that we want to engage with users that help them use Firefox better.

An Event or a series of Events plus some User Attributes may trigger a Message, and when the user acts on the Message, a Deep Link may be processed.

Data collection

Who will have Leanplum enabled?

Users who have a device locale listed in the following code snippet will have Leanplum enabled:

Where does data sent to the Leanplum backend go?

The Leanplum SDK is hard-coded to send data to the endpoint The endpoint is defined by com.leanplum.internal.Constants.API_HOST_NAME at

The user is identified by Leanplum using a random UUID generated by Apple when Leanplum is initialized for the first time (see This unique identifier is only used by Leanplum and can't be tracked back to any Firefox users.

What data is collected and sent to the Leanplum backend?

The Leanplum SDK collects and sends the following information at various times while the SDK is in use.

Sent every time when an event is triggered:

  "action" -> "track"                   // track: an event is tracked.
  "event" -> "Launch"                   // Used when an event is triggered. e.g. E_Saved_Bookmark.
  "info" -> ""                          // Used when an event is triggered. Basic context associated with the event.
  "value" -> 0.0                        // Used when an event is triggered. Value of that event.
  "messageId" -> 5111602214338560       // Used when an event is triggered. The ID of the message.

Sent when the app starts:

  "action" -> "start"                   // start: Leanplum SDK starts. heartbeat
  "userAttributes" -> "{                // A set of key-value pairs used to describe the user.
    "Focus Installed" -> true           // If Focus for iOS is installed.
    "Klar Installed" -> true            // If Klar for iOS is installed.
    "Signed In Sync" -> true            // If the user signed into a Firefox Account.
    "Mailto Is Default" -> true         // If the user has not changed their default mailto handler.
    "Telemetry Opt In" -> true          // If the user has not disabled Sending Anonymous Product Usage.
  "appId" -> "app_6Ao...."              // Leanplum App ID.
  "clientKey" -> "dev_srwDUNZR...."     // Leanplum client access key.
  "systemName" -> "iOS"                 // Fixed String in SDK.
  "locale" -> "zh_TW"                   // System Locale.
  "timezone" -> "Asia/Taipei"           // System Timezone.
  "versionName" -> "55.0a1"             // Fennec version.
  "systemVersion" -> "10.3.1"            // System version.
  "deviceModel" -> "iPhone"             // System device model.
  "timezoneOffsetSeconds" -> "28800"    // User timezone offset with PST.
  "deviceName" -> "sdaswani-31710"       // System device name.
  "region" -> "(detect)"                // Not used. We strip location so this is will be the default stub value in Leanplum SDK.
  "city" -> "(detect)"                  // Same as above.
  "country" -> "(detect)"               // Same as above.
  "location" -> "(detect)"              // Same as above.
  "newsfeedMessages" -> " size = 0"     // Not used. New Leanplum Inbox message(Leanplum feature) count.
  "includeDefaults" -> "false"          // Not used. Always false.

Sent every time a session is renewed or has a state change:

  "action" -> "heartbeat"               // heartbeat: every 15 minutes when app is in the foreground
                                        // pauseSession: when app goes to background
                                        // resumeSession: when app goes to foreground

Sent for every Message:

  "userId" -> "b13b3c239d01aa7c"        // Set by Fennec, we use random uuid so users are anonymous to Leanplum.
  "deviceId" -> "b13b3c239d01aa7c"      // Same as above.
  "sdkVersion" -> "2.2.2-SNAPSHOT"      // Leanplum SDK version.
  "devMode" -> "true"                   // If the SDK is in developer mode. For official builds, it's false.
  "time" -> "1.497595093902E9"          // System time in second.
  "token" -> "nksZ5pa0R5iegC7wj...."    // Token come from Leanplum backend.

Notes on what data is collected

User Identifier

Since Device ID is a random UUID, Leanplum can't map the device to any know Client ID in Fennec nor Advertising ID.


Most of the Leanplum events can be mapped to a single combination of Telemetry event (Event+Method+Extra). Some events are not collected in Mozilla Telemetry. This will be addressed separately in each campaign review. There are three elements that are used for each event. They are: event name, value(default: 0.0), and info(default: ""). Default value for event value is 0.0. Default value for event info is empty string.

Here is the list of current Events sent, which can be found here in the code base:

The first launch after install

  "event": "E_First_Run"

The second launch after install

  "event": "E_Second_Run"

Whenever the App is launched.

  "event": "E_Opened_App"

The user loads a bookmark from home panel.

  "event": "E_Opened_Bookmark"

The user opened a new tab.


  "event": "E_Opened_New_Tab"

The user opens a Pocket trending story


  "event": "E_Opened_Pocket_Story"

The user interacts with search url area.

  "event": "E_Interact_With_Search_URL_Area"

The user saves a bookmark.

  "event": "E_Saved_Bookmark"

The user opened a mailto link from a web page.

  "event": "E_Opened_Mailto_Link"

The user cleared their private data.

  "event": "E_Cleared_Private_Data"

Download videos or any other media

  "event": "E_Download_Media_Saved_Image"

Save password and login from door hanger

  "event": "E_Saved_Login_And_Password"

Signed up for FxA

  "event": "E_User_Signed_Up_For_FxA"

Deep Links

Deep links are actions that can point Firefox to open certain pages or load features such as show bookmark list or open Firefox Account Settings. When users receives a Message, they can click the button(s) on it. These buttons can trigger the following deep links:

  • Link to sync signup/sign in (firefox://deep-link?url=settings/fxa)
  • Link to default search engine settings (firefox://deep-link?url=settings/search)
  • Link to bookmark list (firefox://deep-link?url=homepanel/bookmarks)
  • Link to history list (firefox://deep-link?url=/history)
  • Link to general preferences (firefox://deep-link?url=settings)
  • Link to the mailto preferences (firefox://deep-link?url=settings/mailto)
  • Link to open a new tab (firefox://deep-link?url=settings/newtab)
  • Link to open the user's homepage (firefox://deep-link?url=settings/homepage)
  • Link to open the settings page so the user can clear their private data (firefox://deep-link?url=settings/clear-private-data)
  • Link to open a new private tab (firefox://deep-link?url=homepanel/new-private-tab)

Note these deep links can only be processed from within Firefox (i.e., if they are clicked from outside of Firefox, Firefox will open but nothing further will happen).


Messages are in-app prompts to the user from Leanplum. The user interaction of that prompt will be sent to the Leanplum backend (such as "Accept" or "Show") to track overall engagement with the Message. The Message is downloaded from Leanplum when the Leanplum SDK is initialized at App start, assuming the fulfillment criteria for the Message is met. As mentioned before, the fulfillment criteria is a set of required Events and User Attributes. The fulfillment criteria are set in the Leanplum backend.

The List of current Messages for iOS can be found here: