Skip to content

Latest commit

 

History

History
350 lines (263 loc) · 13.9 KB

mobile-apps.md

File metadata and controls

350 lines (263 loc) · 13.9 KB

gPS Soteria for Apps

Value Based Bidding using Server Side Google Tag Manager & Firestore for Mobile Apps

Overview

This document outlines how Server Side Google Tag Manager for Mobile Apps (sGTM) can be used with Firestore, to pull in profit data and report it to Google Analytics in place of revenue as the conversion value. This enables advertisers to bid to profit with real time conversion uploads.

demo.gif

Gif 1

It should be noted in this demo that we’re changing the e-commerce event conversion value to the profit. If your intention is to use this with bidding, this is a reasonable approach, but be aware that Google Analytics will label the profit as “revenue” in the UI, if you’re using e-commerce events. The solution provides you with full control of where you report this, so you may need to consider which value you use if your goal is to leverage Soteria for reporting purposes.

Background

Value Based Bidding (VBB) is one of the core topics for many clients. There are different levels of maturity with VBB: clients tend to start with a revenue value, and implement tROAS bidding, but as they mature they will move to using a profit or LifeTime Value (LTV) in place of revenue.

Both profit and LTV are sensitive metrics, therefore most clients would not like a determined user to be able to access this information. As a result, clients will tend to either use a proxy value in its place or implement a batch upload strategy using one of the APIs. The former complicates reporting and some clients are uncomfortable with this approach. The latter poses issues due to the lack of support for conversion modelling, and some worry about the impact on bidding, caused by the delay in reporting the conversions in batches.

sGTM has feature parity for modelling with the client side SDK, it happens in real time, and enables pulling in external “sensitive” data, so it operates in the sweet spot between the two existing approaches.

This document outlines how a client could use sGTM to replace revenue with profit, on a “purchase” event, and send it to Google Analytics, in a way that protects that sensitive data.

Prerequisites

  • Server Side Google Tag Manager
  • Access to a Google Cloud project with Firestore in Native mode
  • Access to product level profit data in advance of a transaction
  • Google Analytics or Google Ads for conversions

Architecture

Image 1 provides a high level overview of the core components involved, and outlines the flow. This is high level, please see solution details for further information.

image1.png

Image 1

  1. A GTM app container is used to set up tagging within the mobile app, and is configured with an “in_app_purchase” event.
  2. The client’s mobile app is set up to have an e-commerce purchase event in the data layer: this contains the revenue data. When a purchase is made, the event fires, sending the payload to sGTM.
  3. A custom variable is attached to a tag, triggered by “in_app_purchase” events, which pulls profit data from Firestore and replaces the revenue conversion value with the profit.
  4. The updated event (with profit conversion value) is sent to Google Analytics for Firebase or Google Ads.

Demo

As seen in gif 1, on a demo app there are three products a user can purchase. These can be seen below in table 1, along with the average profit for each of the items.

The revenue value is displayed to the user, and the average profit for each of these items is stored in a separate document in a Firestore collection.

Product Revenue Profit
Blazer $149.99 $72.3
Shoes $79.99 $28.5
T-Shirt $30.99 $14.5
Table 1

On our demo app, after purchasing a pair of socks this is what we can see in the event JSON: image2.png

Image 2

In the data layer we can see a purchase event, with a transaction ID of c1 d2fb77-297d-4e, the total basket value is 149.99 and the item price is 149.99. This is all a determined user would be able to see.

In our Google Tag Manager server container, we have a custom variable that swaps the basket revenue value for the profit, and reports the data to Google Analytics.

In the Firebase DebugView, we can see that the item revenue is unchanged at $149.99. However, we've replaced the basket value with the profit of $72.3.

image3.png

Image 3

We can then configure Google Analytics to use the basket value as a conversion, which can be imported into an ad product and used in bidding. Thus, enabling profit bidding without the profit value ever being on the device for a user to see.

Solution Details

Mobile App

In the app’s code, on the “thank you for your order” screen, an in_app_purchase event is configured. This follows the schema outlined in the docs.

// Example Android Code
Bundle purchaseParams = new Bundle();
purchaseParams.putString(FirebaseAnalytics.Param.TRANSACTION_ID, "T12345");
purchaseParams.putString(FirebaseAnalytics.Param.AFFILIATION, "Google Store");
purchaseParams.putString(FirebaseAnalytics.Param.CURRENCY, "USD");
purchaseParams.putDouble(FirebaseAnalytics.Param.VALUE, 14.98);
purchaseParams.putDouble(FirebaseAnalytics.Param.TAX, 2.58);
purchaseParams.putDouble(FirebaseAnalytics.Param.SHIPPING, 5.34);
purchaseParams.putString(FirebaseAnalytics.Param.COUPON, "SUMMER_FUN");
purchaseParams.putParcelableArray(FirebaseAnalytics.Param.ITEMS,
new Parcelable[]{itemJeggingsCart});

mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.PURCHASE, purchaseParams);
Code 1

GTM App Container

There is nothing special about the Google Tag Manager app container setup. In this demo, a Google Analytics for Firebase tag is set up to send events to our server container, see image 4.

image4.png

Image 4

A purchase_profit event is then configured, see image 5.

image5

Image 5

Firestore

There is a requirement to use Firestore Native, if you've already used Datastore mode, then you'll have to create a new project and store profit data for each product in a Firestore document (read more).

Important ❗: the Firestore API in sGTM currently only supports working with the default database. Ensure that your collection and documents sit within this default database.

The recommended way is to set each Firestore document ID to the product ID, this way it's easy to fetch the right document by a single lookup.

First create a products collection, then add documents to this collection for each product. These documents should have a field with the profit value.

The Firestore collection name, and document field can be set when setting up the variable in sGTM.

image6

Image 6

Server Side GTM

Overview

This is where the magic happens: the data sent from the app (see code 1 and/or image 2) contains the revenue value. In the server side container the revenue value is swapped for the profit value, which is pulled from Firestore, by using a custom “profit variable template”.

An overview of the sGTM flow can be seen below.

Architecture Diagram Analytics

  1. The purchase event triggers the Analytics tag.
  2. The tag has a custom profit variable attached to it to replace the conversion value.
  3. The profit variable uses a custom variable template (see code) to fetch the profit data from Firestore and sum the total profit for all purchased items.
  4. The event is reported to Google Analytics with the updated conversion value.

Set up

Auth

If the server side container is deployed to App Engine or Cloud Run, then Google Tag Manager will use the service account attached to the instance for connecting to Firestore.

If the server side container is deployed in a different Cloud provider to Google Cloud, please follow these additional instructions to attach a Google Cloud service account to the deployment.

This service account needs to have permission to access the Firestore data.

  1. Open the IAM Service Accounts page in the Google project that contains the sGTM container, and make a note of the service account email. Service account email
  2. Open the IAM page for the Firestore project, and press grant access. Firestore project grant IAM access
  3. Add the service account email from step 1, and assign it the Cloud Datastore User role (docs). IAM permissions
Google Tag Manager
  1. Go to the server side container in tagmanager.google.com.
  2. Go to templates -> new variable template.
  3. Click on the three-dot menu on the top right and choose Import.
  4. Select the firestore-value-template.tpl file.
  5. Go to the permission tab and set the permissions for Firestore, ensuring you update the project ID. Template permissions
  6. Save the template.
  7. Go to variables -> new user defined variable and create a “profit” variable from the profit variable template.
  8. Go to tags -> new:
  • Google Analytics: Select an Analytics tag and in the “parameters to add / edit” section replace value with the profit variable.

Google Analytics Tag

Value Calculation

There are different methods for calculating the value built into the tag.

  • Value: This is the default method. The calculation is simply:

    conversion_value = profit * quantity
    
  • Return Rate: If some products are returned more than others, you could calculate the return rate percentage at a product level.

    Then in Firestore you can add the document with both the profit and return rate:

    Firestore screenshot with return rate

    conversion_value = (1 - return_rate) * profit * quantity
    

    If you select this option, you can optionally override the name of the return rate field in Firestore.

  • Value with Discount: Discounts could impact your profit value, and these might be applied at a transaction level. If you use the discount attribute in the items array, you could use this calculation method:

    conversion_value = (profit - discount) * quantity;
    

Tip 💡: If you would like to write your own value calculation, you can do that by adding an additional option to the dropdown after importing the tag in tag manager, and by extending the switch statement in the calculateValue() method to handle your custom approach.

Using AI in place of Firestore

If you're interested in leveraging an AI model instead of static lookups in Firestore, then consider the Phoebe solution on Github.

Disclaimer

Copyright 2024 Google LLC. This solution, including any related sample code or data, is made available on an “as is,” “as available,” and “with all faults” basis, solely for illustrative purposes, and without warranty or representation of any kind. This solution is experimental, unsupported and provided solely for your convenience. Your use of it is subject to your agreements with Google, as applicable, and may constitute a beta feature as defined under those agreements. To the extent that you make any data available to Google in connection with your use of the solution, you represent and warrant that you have all necessary and appropriate rights, consents and permissions to permit Google to use and process that data. By using any portion of this solution, you acknowledge, assume and accept all risks, known and unknown, associated with its usage, including with respect to your deployment of any portion of this solution in your systems, or usage in connection with your business, if at all.