# Analytics & Error Reporting

NOTE

This documentation is the same for both the customer and clerk applications.

Both Customer and Clerk apps use Sentry for error reporting and Firebase Analytics for insights on app usage and user engagement.

# Sentry

Sentry Dashboard (opens new window)

# Configuration

SENTRY_ORG='calblueprint'
SENTRY_PROJECT='dccentralkitchen'
SENTRY_AUTH_TOKEN={secure}

# Usage Examples

Both repos include the following functions in /lib/logUtils.js.

import Constants from 'expo-constants';
import * as Analytics from 'expo-firebase-analytics';
import * as Sentry from 'sentry-expo';

export function logErrorToSentry(errorObject) {
  const { screen, action, error } = errorObject;
  Sentry.withScope((scope) => {
    scope.setExtra('screen', screen);
    scope.setExtra('action', action);
    Sentry.captureException(error);
  });
}

export function logAuthErrorToSentry(errorObject) {
  const { screen, action, attemptedPhone, error } = errorObject;
  Sentry.withScope((scope) => {
    scope.setExtra('screen', screen);
    scope.setExtra('action', action);
    scope.setExtra('attemptedPhone', attemptedPhone);
    Sentry.captureException(error);
  });
}

export function clearUserLog() {
  Sentry.configureScope((scope) => scope.clear());
}

export function setUserLog(customer) {
  Analytics.setUserId(Constants.installationId);
  Analytics.setUserProperties({
    airtable_id: customer.id,
    user_name: customer.name,
    phone_number: customer.phoneNumber,
    installation_id: Constants.installationId,
  });
  Sentry.configureScope((scope) => {
    scope.setUser({
      id: customer.id,
      username: customer.name,
      phoneNumber: customer.phoneNumber,
    });
  });
}

# Auth Error

// LogInScreen.js lines 118-124
logAuthErrorToSentry({
    screen: 'LogInScreen',
    action: 'handleSubmit',
    attemptedPhone: formattedPhoneNumber,
    attemptedPass: password,
    error,
});

Sentry Event Sentry Event Details Resulting error log in Sentry (opens new window)

# Capturing Messages

In addition to error logging, we also record the following messages:

  • Log In Successful
  • Sign Up Successful
  • Guest Login Successful
  • Returning User (a user opens the app while already logged in)
// LogInScreen.js lines 132-139 
Sentry.configureScope((scope) => {
    scope.setUser({
    id: customer.id,
    phoneNumber: formattedPhoneNumber,
    username: customer.name,
    });
    Sentry.captureMessage('Log In Successful');
});

These events help us diagnose issues that aren't directly logged as errors. Sentry.configureScope is used to capture the specific user's information, and Sentry automatically logs other helpful details like device, software version etc.

For example, if a user reports a bug that we thought we already fixed and updated OTA, we can find the Sentry event when the user opened the app and see if their expoAppPublishedTime and expoAppVersion reflect the latest version.

# Relevant PRs

# Firebase Analytics

Go to the Firebase Console (opens new window) to see analytics data and event details.

Note: events logged under the Web App (not iOS or Android) are recorded in development. Only events logged in production will appear under the corresponding platform.

# Configuration

Firebase is configured using the google-services.json for Android and GoogleService-Info.plist for iOS. The additional web configuration in app.json is required for testing in development. Learn more about Expo Firebase Analytics limitations. (opens new window)

# Usage Examples

# Setting user properties

When the user signs up, Analytics tracks the user's ID with their name and phone number.

// SignUpScreen.js lines 167-171
Analytics.setUserId(customerId);
Analytics.setUserProperties({
    name,
    phoneNumber,
});

# Logging events

The example below logs an event when the user opens an external resources link and records the name of the resource. This helps us track user engagement with resources and understand which links they find most helpful.

// ResourceCard.js lines 15-19
Analytics.logEvent('resources_ext_link', {
    name: resource.title,
    screen: 'Resources',
    purpose: 'Opens external link',
});

# Relevant PRs