Data Layer for Mobile

by Ricardo Cristofolini

With everything that has been happening in the World – with Covid especially – more and more people are using apps and online options to do their purchases. Groceries, construction materials, general stuff for the house, and more. As per Business Of Apps, when the iOS App Store launched in 2008, they had 500 apps. In 2020, they ended with around 1.85 million different apps for users to download. Android, in 2020, had approximately 2.56 million apps available in Google Play Store.

Looking to the future, Statista states that Mobile Apps are expected to generate over $935 billion in revenue by 2023.

In relation to users, the same site estimates that 21% of Millenials open an app 50+ times per day, 49% of people open an app 11+ times each day, 69% of all US digital media time comes from mobile apps and the average smartphone owner uses 10 apps per day and 30 apps each month.

There’s a lot of information in these numbers and they all support the fact that apps are growing, will continue to do so, and nothing is more important than starting to understand (or keep working on it) how users are using them. GA4 and Firebase SDK are here to help you, and the sooner you start, the better.

Data Layer – Let’s talk about…. A Layer of Data! HA!

It’s not a mystery that having a Data Layer on a website can provide a huge variety of data to help you make better decisions based. If you’re still not sure what the Data Layer is, or how important it is, please check this article “WTF is a Data Layer & Why Does is Matter”.

Although you don’t need to read that article to understand this one,  it will help.

So, let’s have a look at other types of Data Layer. Not for Website, but the one for Apps. This is important considering Google Analytics 4 especially if a dual implementation is taking place on your site, assuming that it’s a Web app and/or it will have an app version.

Finally, by the end of this article, you will be able to understand what is necessary to start writing your app Data Layer based on your app coding language, different types, and where to go for more information. It’s important to mention this is a fairly technical article, so if this is your first time coding, or implementing the tracking events in an app, it may be a little hard to follow.

Moving forward. Did you say Data Layer for apps?

That’s right. Just like a website, users will have to interact with your app. They will log in, log out, tap a button, contact your company through a form, purchase a product, etc. And just like a website, you probably want to know what users are doing in your app so you can make it better.

Roughly, the difference between the web and app Data Layer is that a website has all the pages interlinked with a single domain name. The Data Layer here will be implemented directly in the page – for most cases – or in a separate file – and will be written with JavaScript. The web application on the other hand, is a software or program you can access using any web browser, that, depending on the language used to create the apps, will vary from Swift, Objective-C, Android, C#, C++ and so on.

Here are a couple of things to take into consideration:

  • Depending on what you’re implementing, the structure of the Data Layer for iOS is different from a Data Layer for Android, which is different from the Web app. For example:

Web Data LayeriOS – Swift Data Layer
gtag(‘event’, ‘login’, {  ‘method’: ‘Google’});Analytics.logEvent(“login”, parameters: [  “method”: method as NSObject  ])

  • The call for these events will be different as well. You won’t be using GTM (in most cases) to pass the data to GA. Instead, the Firebase SDK will do the trick.
  • Default tracking events are different compared to the Website Data Layer.
  • There are different ways to implement Analytics in your apps (and we will be covering all of them).
  • The Analyst and the Developer team will have to work closely together if a dual implementation is happening.
  • There is a significant difference between QAing your app Data Layer vs QAing your website Data Layer. Usually, the web Data Layer QA would take place in the web console and the App Data Layer QAing would happen either in an external software to check the links being sent to GA4 or in the Debug Mode in GA4.

First things first. Native Implementation.

If a Native implementation is what you’re looking for, Firebase SDK will be your best friend during the development. We’re not going deep into how to implement Firebase to your app (although this would be another nice topic for an article), but you can find all the information in the links below.

To have your Data Layer in place inside your app, it’s necessary to add Firebase to your app. The details of the Implementation you can find in the Firebase Documentation, but here are the steps:

WebiOSAndroid
Create a Firebase projectRegister your app with FirebaseAdd Firebase SDKs and initialize Firebase(Optional) Install CLI and deploy to Firebase HostingAccess Firebase in your appCreate a Firebase Project
Register your app with Firebase
Add a Firebase configuration file
Add Firebase SDK to your app
Initialize Firebase in your app
Option 1 (recommended):
Create a Firebase project
Register your app with Firebase
Add a Firebase configuration file
Add Firebase SDKs to your app
Option 2:Add Firebase using the Firebase Assistant

Not a lot of differences, right?

Do I have to code ALL the events after that?

Well, no. Once you have the Firebase SDK implemented, Analytics is nice enough to automatically log some events by default. They are based on the basic interactions with the app and/or site and as long as you use the SDK or gtag.js, you shouldn’t need to write any additional code.

All these events are collected for both Android and iOS apps unless stated otherwise. That means, depending on the event, it will be tracked automatically for Apps but not for Web and vice-versa.

For example:

The file_download event will be automatically tracked for Web, but not for apps. On the other hand, ad_click will be automatically tracked for App, but not for Web. The full list of events can be found here, but it should be pretty straightforward to differentiate them in the documentation.

What about the differences you talked so much about?

For different platforms (Android, iOS and/or Web app), it’s likely you will need different approaches for the App Data Layer Implementation. The reason is simply because of the code language. Writing code in XCode is different from writing code in Android Studio, for example.

You will have, of course, some similarities that will help you go through all the implementation. We’re not talking 100% differences between the code language. A logEvent will be a logEvent in all languages. Set user ID will be using setUserId for all of them. And so on.

Let’s start with something simple such as setting user ID.

Android vs Swift vs Objective-C vs C++

AndroidSwiftObjective-CC++
mFirebaseAnalytics.setUserId(“123456”);Analytics.setUserID(“123456”)[FIRAnalytics setUserID:@”123456″]analytics::SetUserId(“123456”);

So, any similarities here? Here’s the breakdown of the Android structure:

What about the Swift (iOS) structure:

For the complete guide on the Set User ID, you can check Google’s documentation, but I believe you get the idea.

Let’s have a look at another example, maybe with a little bit more code.

Log events will be by far the most used structure in your app Data Layer, so let’s have a look at this structure. On a quick summary, events provide a better understanding of what is happening in the app among user actions, system events, errors, etc.

Once you have configured the Firebase App instance, the method used to log events is logEvent(). A quick note, events can be custom, or use those available in the SDK. We strongly suggest you use the default ones as much as possible because using custom events has a cost… in other words, a limit.

Now, it’s important to say that we noticed some other blogs mentioned not utilizing the recommended events in GA4 (and probably the Firebase equivalents), which could cause you to lose out on some tracking that might be baked into GA4’s reports either now, or at a later date. Is that a fact? Maybe, only time will tell as GA4 is being updated constantly. For example, it’s recommended for GA4 that the event name = login and event parameters collected are “method”. While there may not be a reason to align with this recommendation now, they may roll out some sort of reporting that automatically recognizes that event and parameter later on.

Let’s take a look at how to log a Select Content event. The main purpose of this event is to inform you that a user has selected some content of a certain type in the app. The content can be any object available in your app. Furthermore, this event can help you identify popular content and categories of content.

And by default I mean you have to type that in the code, not that it will be collected automatically.

For Swift, that event would go something like this:

Analytics.logEvent(AnalyticsEventSelectContent, parameters: [  AnalyticsParameterItemID: “id-\(title!)”,  AnalyticsParameterItemName: title!,  AnalyticsParameterContentType: “cont”  ])

If you’re using Objective-C for iOS, the structure will look different and you can check it here.

Java Android, the same event would be translated like this:

Bundle bundle = new Bundle();bundle.putString(FirebaseAnalytics.Param.ITEM_ID, id);bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, name);bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, “image”);mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle);

Android has also Kotlin + KTX that you can check here.

And finally, for Web, Select Content would be:

analytics.logEvent(‘select_content’, {  content_type: ‘image’,  content_id: ‘P12453’,  items: [{ name: ‘Kittens’ }]});

Check Google’s Documentation for a full list of the constants available globally alongside Classes and Categories.

Got it, but my app is Hybrid. How does the Data Layer work for this?

That’s a good question and if you thought about it, you probably have already built or worked with a Hybrid app before. So, different from the actual Native build where you use what we mentioned above and more, hybrid apps are web apps built with HTML/JavaScript that later on, uses a native framework to function.

Can you provide an example?

Sure. Let’s have a look at Apache Cordova plugin which is a mobile application development framework. After installing the plugin, here’s the piece of code to set user ID and log event, just to be consistent on the examples we already provided.

Set User Id:

cordova.plugins.firebase.analytics.setUserId(“12345”);

Where, “12345”, based on Google’s Privacy Policy, will be populated dynamically by the user Id generated by your internal system, for example.

Log Event:

cordova.plugins.firebase.analytics.logEvent(“my_event”, {param1: “value1”});

Now, events, in this case, can be divided into Custom EVents and Predefined Events. Remember that I mentioned that Firebase SDK has some default events and it’s best to use these as much as possible? This is how you differentiate from both of them using Apache Cordova plugin:

Custom Events:

function App() {  return (    <View>      <Button        title=”Add To Basket”        onPress={async () =>          await analytics().logEvent(‘basket’, {            id: 3745092,            item: ‘mens grey t-shirt’,            description: [’round neck’, ‘long sleeved’],            size: ‘L’,          })        }      />    </View>  );}

Predefined Events:

function App() {  return (    <View>      <Button        title=”Press me”        // Logs in the firebase analytics console as “select_content” event        // only accepts the two object properties which accept strings.        onPress={async () =>          await analytics().logSelectContent({            content_type: ‘clothing’,            item_id: ‘abcd’,          })        }

The reason why one would use Custom Events instead of Predefined Events is simply that the Predefined Events can be limited. Unfortunately, it doesn’t provide everything and, as one app is different from another, eventually something unique will have to be tracked. This is where Custom Events comes in.

The full Documentation for Cordova Plugin Firebase Analytics can be found here and here.

What about Ecommerce?

Ecommerce is an important part of any website or app if your company sells products. Just like websites, information on how users are behaving and what they are doing in the apps can lead to better UI, UX, buy flow, revenue, and more.

Keep in mind we’re not going to explain the full Ecommerce funnel and all its functionalities as the objective of this article is to show the differences between the coding languages. If you’re interested in going deep into this, the full documentation from Firebase related to Ecommerce can be found here.

Usually, there are several steps in an Ecommerce structure.

  • Select a product from a list
  • View product details
  • Add/remove a product from the cart
  • Initiate the checkout process
  • Make purchases or refunds
  • Apply promotions

Inside all of these actions, we have the products that are being dealt with. For apps, products can be organized as an array of items and used by ecommerce events later on. Let’s have a look at a few examples.

Product Array
SwiftJava Android
// A pair of jeggingsvar jeggings: [String: Any] = [  AnalyticsParameterItemID: “SKU_123”,  AnalyticsParameterItemName: “jeggings”,  AnalyticsParameterItemCategory: “pants”,  AnalyticsParameterItemVariant: “black”,  AnalyticsParameterItemBrand: “Google”,  AnalyticsParameterPrice: 9.99,]Bundle itemJeggings = new Bundle();
itemJeggings.putString(FirebaseAnalytics.Param.ITEM_ID, “SKU_123”);itemJeggings.putString(FirebaseAnalytics.Param.ITEM_NAME, “jeggings”);itemJeggings.putString(FirebaseAnalytics.Param.ITEM_CATEGORY, “pants”);itemJeggings.putString(FirebaseAnalytics.Param.ITEM_VARIANT, “black”);itemJeggings.putString(FirebaseAnalytics.Param.ITEM_BRAND, “Google”);itemJeggings.putDouble(FirebaseAnalytics.Param.PRICE, 9.99);

As you can notice here, although the way information is presented is differently, the structure is similar. In both cases, we have a variable name and type, and parameter name and data available.

Swift:

AnalyticsParameterItemID: “SKU_123”,

Java Android:

itemJeggings.putString(FirebaseAnalytics.Param.ITEM_ID, “SKU_123”);

It’s important to highlight that the purchase event replaces the ecommerce_purchase and is different from the in_app_purchase event, which is reported automatically. The first one is related to products that your company sells. The latest is related when a user completes a purchase that is processed by the App Store on iTunes or by Google Play.

Now that we have the Product array, let’s select a product from a list. The idea here is the same as an impression list that will log all the items presented to the users. In the end, a view_item_list will be logged:

Select a Product
SwiftJava Android
// Add item indexesjeggings[AnalyticsParameterIndex] = 1boots[AnalyticsParameterIndex] = 2socks[AnalyticsParameterIndex] = 3
// Prepare ecommerce parametersvar itemList: [String: Any] = [  AnalyticsParameterItemListID: “L001”,  AnalyticsParameterItemListName: “Related products”,]
// Add items arrayitemList[AnalyticsParameterItems] = [jeggings, boots, socks]
// Log view item list eventAnalytics.logEvent(AnalyticsEventViewItemList, parameters: itemList)
Bundle itemJeggingsWithIndex = new Bundle(itemJeggings);itemJeggingsWithIndex.putLong(FirebaseAnalytics.Param.INDEX, 1);
Bundle itemBootsWithIndex = new Bundle(itemBoots);itemBootsWithIndex.putLong(FirebaseAnalytics.Param.INDEX, 2);
Bundle itemSocksWithIndex = new Bundle(itemSocks);itemSocksWithIndex.putLong(FirebaseAnalytics.Param.INDEX, 3);
Bundle viewItemListParams = new Bundle();viewItemListParams.putString(FirebaseAnalytics.Param.ITEM_LIST_ID, “L001”);viewItemListParams.putString(FirebaseAnalytics.Param.ITEM_LIST_NAME, “Related products”);viewItemListParams.putParcelableArray(FirebaseAnalytics.Param.ITEMS,        new Parcelable[]{ itemJeggingsWithIndex, itemBootsWithIndex, itemSocksWithIndex });analytics.logEvent(FirebaseAnalytics.Event.VIEW_ITEM_LIST, viewItemListParams);

In both cases Indexes, Item list ID and Name, and item array are added. Finally, ViewItemList event is logged at the end and, although the Android’s code looks “scarier” when compared to the Swift code, they are doing the same thing.

The same idea can be applied to the other steps. You can find the full list here.

Conclusion

From all the information that we presented in this article, It’s important to understand that Web Apps are different from Websites. As you noticed, I referred over and over again to these two and their singularities because I believe it’s important to understand that difference.

With Firebase SDK implemented in your app, from the start you will already have initial default tracking data in the GA4 property – just like the GA4 Web basic implementation. That means if you have an Android, iOS, and Web app, once the SDK is properly implemented, all the data will be available in a single GA4 Property through Data Streams…. But that’s a topic for another article.

What do you guys think about this? Do you use the actual default events or custom ones? Frameworks to code your apps or native implementation?

Ricardo Cristofolini

Implementation Specialist

I’m passionate about what I do. If you meet my manager or co-workers, they would say I’m a team player, engaged and always excited to learn something new. Like everyone else I have some flaws. However I’m not afraid to work around those to bring the best in myself and for the company.

See more posts from Ricardo