Available for the following Plan types:
FullStory Enterprise*
FullStory Business*
FullStory Free
*with the following add-on:
FullStory for Mobile Apps
Available to the following User roles:
Admin
Architect
Standard
Summary
Using FullStory and Crashlytics together provides unparalleled insights into app issues so you can debug issues and iterate faster.
When a crash is reported to Crashlytics, an engineer can use the session replay to see visually what the user did leading up to the moment of the crash.
The Goal:
This documentation aims to provide common use cases for integrating FullStory and Crashlytics and technical guidance on how to do so for iOS and Android. Feel free to contact FullStory support for more information, or share your success story with us!
Use Cases
Add a FullStory session replay link to a Crashlytics report
With FullStory for mobile apps, you can retrieve a link to the beginning of the session replay to be attached to the Crashlytics report. When viewing an issue in Crashlytics, navigate to the session replay link and watch the steps to reproduce without ever having to coordinate with end-users to get their feedback about what happened. This enables engineers to quickly and accurately reproduce the crash and fix the issue.
Capture user journeys along with app state
In addition to sharing a replay link, you can also share point-in-time data via logging. At any point in your application, you may wish to log certain messages to Crashlytics and FullStory, so you can easily navigate back and forth between Crashlytics and FullStory to find valuable information about specific crashes and errors.
By logging the app state as your users journey through your app, you can easily trace back the cause of an exception as it relates to user interaction and also understand the app state when the crash occurred.
Identify users who experienced a crash
When diagnosing and working with an issue, it’s often helpful to zoom-in to a certain set of users to understand how they are affected. Both FullStory and Crashlytics allow you to identify the user by setting a userID. Navigate between FullStory and Crashlytics for a user and have side by side data for the chosen user.
Prioritize non-fatal Errors
Non-fatal errors can still have a negative impact on user experience. While trying to understand your users’ overall experience, it may be valuable to investigate how non-fatal errors are getting in their way. Certain non-fatal errors may be caught and handled but may still stop your users from being able to use key functionalities and thus cause frustration and churn. Use custom events in FullStory to surface any errors that may have negative impact. All custom events are indexed, which means you can search for non-fatal errors and prioritize them accordingly.
Implementation
Add a FullStory session replay link to a crash report
- Setup your Crashlytics SDK and get crash reports via Crashlytics
- Setup FullStory data capture for Android or iOS
-
Implement your app to respond when FS is ready
Android |
@Override |
iOS |
func fullstoryDidStartSession(_ sessionUrl: String) { |
4. After retrieving the FS session URL, use the following snippet to attach the sessionURL as a key-value pair to a Crashlytics report:
Android |
FirebaseCrashlytics instance = FirebaseCrashlytics.getInstance(); |
iOS |
Crashlytics.crashlytics() |
5. When a crash occurs, you will see an issue under Crashlytics in your Firebase console. Note that when an app crashes, the session will terminate, meaning that the end of this session is where the crash had occurred. In each session under the issue, you can go to the Keys tab, and see the FullStory session URL:
Capture user journeys along with app state
- You can choose to send the session URL along with custom log messages to Crashlytics log, and also mark them in FS playback using FS.event or FS.log:
Android |
String fsCustomEventTag = "CrashlyticLog"; |
iOS |
let fsSessionURL = FS.currentSessionURL |
2. View your custom logs for an issue under the Logs tab:
3. And then you can navigate to the FullStory session URL. You will see custom events on the right hand pane during replay, and custom logging will show up under dev tools to allow you to identify the point of time when the logs were sent to Crashlytics. These app state breadcrumbs help you better understand the exception.
See the logs and event in FullStory playback like below:
Notice the blocked-out areas of the app visible during replay. These are our default privacy controls in action. To learn more about how we’ve designed our privacy controls for mobile apps, check out this article on our engineering blog: https://bionic.fullstory.com/private-by-default-mobile-analytics/
Set user identifiers across FS and Crashlytics
-
When you are able to identify the user, you can send the user identity to Crashlytics
-
At the same time, send the same user id to FullStory using FS.identify, with optional userVars, to help you identify users that experience a crash.
Android // when user is identified(logged in), create a Map for the userVars
Map<String, String> userVars = new HashMap<>();
userVars.put("userID", "testuser3");
userVars.put("displayName","crashlytics user3");
userVars.put("email","testeamil@gmail.com");
// send user identity and userVars to FS
FS.identify(userVar.get("userID"),userVar);
// send user identity to Crashlytics
instance.setUserId(userVar.get("userID"));iOS // when user is identified(logged in), create a Map for the userVars
var userVars = [String: String]()
userVars["userID"] = "testuser3"
userVars["displayName"] = "crashlytics user3"
userVars["email"] = "testeamil@gmail.com"
// send user identity and userVars to FS
FS.identify("testuser3", userVars: userVars);
// send user identity to Crashlytics
Crashlytics.crashlytics().setUserID("testuser3")React Native ES6 Promise
// when user is identified(logged in), create a Map for the userVars
var userVars = {}
userVars["userID"] = "testuser3"
userVars["displayName"] = "crashlytics user3"
userVars["email"] = "testeamil@gmail.com"
// send user identity and userVars to FS
FS.identify("testuser3", userVars);
// send user identity to Crashlytics
crashlytics().setUserID("testuser3").then(() => {})
async / await
// when user is identified(logged in), create a Map for the userVars
var userVars = {}
userVars["userID"] = "testuser3"
userVars["displayName"] = "crashlytics user3"
userVars["email"] = "testeamil@gmail.com"
// send user identity and userVars to FS
FS.identify("testuser3", userVars);
// send user identity to Crashlytics
await crashlytics().setUserID("testuser3") -
By doing this you are now able to view and identify issues in Crashlytics by how many users are affected:
-
User ID is also shown in the Data tab under an issue:
-
Search for a certain user to investigate any user that is affected by crashes (Note that FullStory does not capture crash events for iOS as of right now, but you can still see all the sessions from a certain user without adding the crashed event filter):
-
Optionally, build your own deep link into FullStory to be passed into Crashlytics, or vice versa:
a. Get the link from your browser when you have a built out search in FullStory, something like this: <FS_USER_LINK> =
https://app.fullstory.com/ui/<ORG_ID>/segments/everyone/people:search:(:((UserAppKey:==:%22<USER_ID>%22)):():():():)/0(Android only): <FS_USER_CRASH_LINK> =
https://app.staging.fullstory.com/ui/5<ORG_ID>6EM/segments/everyone/people:search:(:((UserAppKey:==:%22<USER_ID>%22)):():(((EventType:==:\"crashed\"))):():)/0b. Get a list of crashes for specific users in Crashlytics by searching for a user ID, getting the link from your browser, something like this:
<CRASHLYTICS_LINK> =
https://console.firebase.google.com/u/0/project/<PROJECT_NAME>/crashlytics/app/<PLATFORM:APP_ID>/search?time=last-seven-days&type=crash&q=<USER_ID>c. Pass the deep links into FullStory or Crashlytics. Note that a different keys should be used for each deep link, if the same key is used, the latest value being passed will override the previous ones:
Android
// optionally attach the user specific links between platforms
// Hardcoding the query link, use with caution
Map<String, String> userVars = new HashMap<>();
// call setUserVars or you can set these vars during identify
userVars.put("crashlyticsURLAndroidDemoapp",<CRASHLYTICS_LINK>);
FS.setUserVars(userVar);
// add FS links to the crash report as custom key
instance.setCustomKey("FSUserSearchURL",<FS_USER_LINK>);
instance.setCustomKey("FSUserCrashedSearchURL",<FS_USER_CRASH_LINK>);iOS
var userVars = [String: String]()
// call setUserVars or you can set these vars during identify
userVars["crashlyticsURLiOSDemoApp"] = <CRASHLYTICS_LINK>
FS.setUserVars(userVars);
// add FS links to the crash report as custom key
Crashlytics.crashlytics()
.setCustomValue(<FS_USER_LINK>, forKey: "FSUserSearchURL")React Native
ES6 Promise
// call setUserVars or you can set these vars during identify
userVars["crashlyticsURLRNDemoApp"] = <CRASHLYTICS_LINK>
FullStory.setUserVars(userVars)
// add FS links to the crash report as custom key
crashlytics()
.setAttribute('FSUserSearchURL', <FS_USER_LINK>).then(() => {})
async / await
// call setUserVars or you can set these vars during identify
userVars["crashlyticsURLRNDemoApp"] = <CRASHLYTICS_LINK>
FullStory.setUserVars(userVars)
// add FS links to the crash report as custom key
await crashlytics()
.setAttribute('FSUserSearchURL', <FS_USER_LINK>) -
Now you are able to go back and forth when investigating a certain crash like so:
a. Identify a user in Crashlytics:
b. Get the link to the FullStory session replay so you can see all the crashes from all users or
just the current user. Feel free to build on top of these prebuilt links and create your own
search or segment.
For Android, retrieve all crashes:
c. Get the most recent URL to Crashlytic's user search page, so you can go directly to see all the crashes for this user:
Send FS events during non-fatal exception handling
-
Crashlytics automatically reports fatal crashes, but you can optionally send non-fatal crashes when you catch one
- You can also send a log or an event to FullStory to help you pinpoint the error when it happens during session replay
Android |
try { |
iOS |
do { |
React Native |
ES6 Promise
|
3. This will help you pinpoint the non-fatal error that occurred during a user session:
a. Pinpoint the error occurrence in FullStory playback
b. In this case even though the exception is non-fatal and did not crash the
app, it prevents your user from clicking on “purchase” button
c. You can easily build searches and filters to identify the most crucial exceptions in your
workflow:
d. Once you’ve pinpointed the exception that you would like to prioritize, you can then view the
non-fatal exceptions in Crashlytics