Hi, there, Firebase developers! We wanted to let you know about some important changes coming your way from Google Analytics for Firebase that will affect how we help you measure user engagement and sessions. This might also affect any BigQuery queries you might have written, so let's get right into the changes, shall we?

What's changing with sessions?

Up until now, sessions were measured using the following formula:

session_start was triggered when the foreground for more than 10 seconds

Google Analytics for Firebase would trigger a session_start event if there was no current session, and the app was in the foreground for more than 10 seconds

Sessions are complete after 30 minutes in the foreground

A session would be considered completed when more than 30 minutes had passed since the app was in the foreground

  • This meant that if a user used your app for a little while, briefly switched to another app to respond to a chat message, then switched back to your app, that would still count as one session.
  • Both of these time values could be configured locally on the client
  • If you wanted to group events by session in BigQuery, you'd essentially need to do that manually. That is, you'd need to select all events for the same pseudo_user_id that occurred 10 seconds before a session_started event, and keep going until you hit a 30 minute gap. As you might expect, grouping events by session was a not-very-fun experience for BigQuery developers.

With the latest version of the Firebase SDK, we're going to be changing how a session is measured. Specifically:

No more 10 second delay

Google Analytics for Firebase will trigger a session_start event as soon as your app goes into the foreground now. There's no more 10 second delay.

You can now extend sessions past 30 minutes

Like before, a session is considered finished when more than 30 minutes has passed since your app was in the foreground…

  • ...except that you can now add an extend_session parameter to any event which tells Analytics that, even if this event is triggered in the background, this event is considered part of an active session. This is useful if you have an app that people frequently use in the background, like a music or navigation app.

  • We will now add new properties to nearly every event that let you know what session they were in. Specifically, you'll now have a ga_session_id parameter which is a unique identifier for the session, and a monotonically increasing ga_session_number parameter to help you count the number of sessions for this user.

So, what do all of these changes mean?

In the Firebase console, the biggest change you'll notice is that your app will have more sessions, because we'll be counting instances where users interact with your app for less than ten seconds. This also means that any kind of "average _some_event_ per session" stat will decrease, since the number of sessions is going up.

Analyze with BigQuery

On the BigQuery side of things, these new event parameters will make your life a whole lot easier. Analyzing anything by session should be really straightforward now -- you just need to group them by ga_session_id. So calculating your own "average xxx per session" values will be a lot easier in BigQuery.

For example, here's a query where we calculate how many level_complete_quickplay events an average user generates per session:

SELECT AVG(total_quickplays) as average_quickplays_per_session FROM (
  SELECT COUNT(event_name) as total_quickplays,
    (SELECT value.string_value FROM UNNEST (event_params) WHERE key = 
      "ga_session_id") as session_id
    FROM `firebase-public-project.analytics_153293282.events_xxxxxxxx` 
  WHERE event_name = "level_complete_quickplay"
  GROUP BY session_id
  HAVING session_id IS NOT NULL
)

And if you want to figure out, say, how many sessions it typically takes before somebody makes a purchase, you can do that by analyzing the ga_session_number parameter.

What's changing with user engagement?

In the past, Firebase measured total user engagement by recording the amount of time your user spent with the app in the foreground and then sending down those values (as incremental measurements) as user_engagement events. You could then calculate the total amount of time a user spent within your app by adding up the values of the engagement_time_msec parameter that were sent with each of these events.

user_engagement could be triggered on app crashes

These user_engagement events were typically sent when a user a) Sent your app into the background, b) Switched screens, c) Crashed, or d) Used your app for an hour. As a result, it was very common to see user_engagement events sent alongside events like app_exception or screen_view events. To the point where we asked ourselves, "Why are we sending down all these extra events? Why not just send engagement time as a parameter with these other events we're already generating?"

We're adding engagement_time_msec

And so that's exactly what we're going to do, starting in early 2019. You will still occasionally see separate user_engagement events, but you will also start seeing engagement_time_msec parameters added to other events automatically generated by Google Analytics for Firebase. We're going to start with screen_view, first_open and app_exception events, but you might see them added to other events in the future.

What do these changes mean to you?

On the Firebase console, nothing should change. Your app might end up using a little less data, since you're no longer sending down so many separate user_engagement events, but otherwise, nothing else should look different.

BigQuery implications

On the BigQuery side of things, you'll need to alter your queries slightly if you were calculating important metrics by filtering for user_engagement events. If you were, you'll need to alter those queries by looking for events that contain an engagement_time_msec parameter.

For example, here's a query that calculates the total user_engagement time for each user by summing up the engagement_time_msec parameter for user_engagement events. This might work today, but it will be inaccurate in the future.

SELECT SUM(engagement_time) AS total_user_engagement 
FROM (
  SELECT user_pseudo_id, 
    (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 
      "engagement_time_msec") AS engagement_time
  FROM `firebase-public-project.analytics_153293282.events_20181003` 
  WHERE event_name = "user_engagement"
) 
GROUP BY user_pseudo_id

So here's that same query, modified to look for all events that might have a engagement_time_msec parameter

SELECT SUM(engagement_time) AS total_user_engagement 
FROM (
  SELECT user_pseudo_id, 
    (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 
      "engagement_time_msec") AS engagement_time
  FROM `firebase-public-project.analytics_153293282.events_20181003` 
)
WHERE engagement_time > 0
GROUP BY user_pseudo_id

The nice thing about that second query is that it works both with the old way of measuring user engagement and the new one, so you can modify your BigQuery queries today, and everything will still work just fine when the new changes go into effect.

Update: Well, it took a little longer than planned, but this feature launched in April of 2020. If you've been using this second BigQuery query all along, then congratulations! Everything should continue working as before. If not, well, there's no better time to switch over.

We hope that these changes make your life a little easier in the long run, and offer only a minimal amount of disruption in the short term. In the meantime, if you have any questions, feel free to reach out on StackOverflow, or any of our official support forums.

Happy analyzing!