A few months ago, at Google I/O, we announced the beta of App Check, Firebase’s new mobile and web API security solution. App Check is an additional layer of security that protects access to your services by attesting that incoming traffic is coming from your app, and blocking traffic that doesn't have valid credentials. Right now, App Check is available for Cloud Storage, Realtime Database, and Cloud Functions for Firebase. In case you missed the launch, check out our introduction video to see how App Check works.
Today, we’re happy to announce three new features we’ve added to the App Check beta: support for App Attest on iOS, configurable time-to-live values (TTLs) for tokens, and support for protecting non-Firebase backends with App Check.
We know how important security is, so we wanted to make sure we’re integrated with the latest app attestation providers for our main platforms, and that includes iOS. To that end, we’ve added support on iOS for App Attest, Apple’s app attestation technology that was recently featured at Apple’s WWDC conference.
App Attest can be used to assert that a request comes from a legitimate instance of your app that satisfies three conditions:
You can use App Attest as an App Check provider on any iOS device that supports it. On devices without App Attest support, you can continue to use DeviceCheck with App Check. See our developer guide to learn how to use App Check with App Attest on iOS.
To give you the power to choose how you want to balance security and usability in your app, we’ve added the optional ability to set the TTL of App Check tokens. By using a short TTL, you optimize for increased security; on the other hand, a longer TTL can improve responsiveness and minimize quota usage. You can even customize the TTL individually per attestation provider. Configurable TTLs are supported when using App Attest, Device Check, SafetyNet, reCAPTCHA v3, and custom providers.
If you use your own backend services alongside Firebase, App Check can still help you! With our newest beta, you can protect your non-Firebase resources with App Check. This protection is currently possible on any backend service or service proxy that can run the Firebase Admin SDK for Node.js, including Cloud Run & GKE instances, and even bare metal servers.
If you already use App Check with RTDB, Storage or Functions, it is now really easy to extend App Check’s protections to your own server as well. It only takes a few lines of code on the client and on the backend to start protecting your resources today. Take a look at our guides for iOS, Android, and web to learn how.
This is part of a series of articles about app quality. Here is an overview of all the other articles:
Apps and games have evolved rapidly in recent years, and user expectations for high performance have increased right alongside them. Today’s users don’t just demand speed and performance — they reward it. A 2019 study found that retail sites saw 8% more conversions when they reduced their mobile site load times by one-tenth of a second. And travel sites boosted conversions by just over 10%.
As you reach more users across different devices, locations, OS versions, and networks, optimizing performance becomes even more of a moving target. To understand the unique context behind performance issues, you need actionable insights about your app performance from a user's perspective. With performance data that allows you to spend less time putting out fires, you can devote more time to creating delightful experiences knowing that no bug or glitch will slip through the cracks.
With performance data that allows you to spend less time putting out fires, you can devote more time to creating delightful experiences knowing that no bug or glitch will slip through the cracks.
In this article, we’ll explore some Firebase Performance Monitoring features that can help you keep an eye on your app’s performance and understand the experience from a user's point of view.
Real-time app performance metrics
Releasing a new feature that performs well for every user — no matter their location, device, or network speed — can be challenging if you don’t have the timely information you need to gauge performance across a range of variables. When poor performance and low app ratings occur, you need clear insights to deliver an experience worthy of a 5-star review.
Firebase Performance Monitoring processes your app performance data in real time so you can monitor new releases during development and post-launch. For instance, you can gather performance data from Firebase Emulators or virtual devices on Firebase Test Lab to test your app locally before launch. And after launch, you can get insights about metrics related to screen rendering and network requests to learn how your app is performing among different user segments.
By learning how your app responds for different groups of users, you can quickly take action to fix any errors and ensure users won’t delete your app to find one that works better on their device.
Performance Monitoring dashboard highlighting real-time metrics
Customizable Metrics Board
In the first blog post of this series, we highlighted some standard app performance metrics to keep top-of-mind, such as app start-up time, screen rendering performance, and network performance. However, sometimes the influx of real-time data after a big release can feel overwhelming, and identifying where you should focus and take action can be a daunting task.
With the revamped Performance Monitoring dashboard, you can customize your app performance metrics board to highlight the most important metrics for your app. For example, if you’re releasing updates on a shopping app, you can select and track slow-rendering frames on the checkout screens. This helps ensure your customers are enjoying a seamless experience from start to finish. You can also break down your key metrics by country, device, app versions, and OS level for a deeper dive into your performance data.
By learning how quickly your app responds for different groups of users, you can take action to fix latency issues and ensure users won’t delete your app to find one that works better on their device.
Additionally, Performance Monitoring allows you to implement custom code traces, which help monitor the performance of your app between two points in time. You can also create your own traces to capture performance data associated with specific code in your app. For example, you could use custom code traces to measure how long it takes your app to load a set of images and make sure the graphics aren’t causing too much lag.
Compare performance between app versions
Retaining a diverse user base isn’t easy without understanding how specific user segments are engaging with your app — especially when their experience isn’t up to par. To make sure every new release performs at its best once it reaches a large number of users, you can use the new Performance Monitoring dashboard to identify app performance changes that need immediate attention.
The metrics board enables metric performance tracking across versions. If your latest release calls a new API at start-up, you can track latencies in app start time between the latest version of your app and previous versions. The traces table is especially helpful to understand how your traces are trending across selected time ranges. That means you no longer have to wait for app store reviews or support tickets to know when your app performance is lagging.
Performance Monitoring traces table
Track trends, regressions, and severe issues
One of the most important ways to grow and engage your audience is by constantly releasing new features and updates to your app. But any code or configuration changes to your app or any of its many dependencies carry a risk of degrading your app’s performance or causing issues with user experience. For example, if your e-commerce app makes dozens of API calls to fetch your catalog and product details, users might experience frustrating lags during their shopping experience.
By tracking trends and regressions with Performance Monitoring, you can quickly act on the most critical issues and get ahead of low ratings on the app store.
Improve user retention with Performance Monitoring
GameNexa Studios, an India-based app developer, seized an opportunity to invest in improving its app quality when their ad sales were disrupted by COVID-19. By combining Firebase Performance Monitoring and Firebase Crashlytics, the team gained actionable insights about its user base and improved their most popular app’s experience across the board. And by reducing the number of performance issues affecting its users, GameNexa ended up boosting both user retention and session duration, and increased in-app purchases by 2.5X.
Stay ahead of app stability and performance issues
To deliver the fast, consistent experience app that users expect, you need a strategy backed by tools that help you act quickly and fix significant issues on the fly. With detailed, actionable data and insights from Firebase, app developers and product managers can make smarter decisions before launch, tackle urgent issues swiftly after releasing an update, and quickly and confidently roll out new features that keep users coming back.
To get started with Firebase Performance Monitoring, integrate the Performance Monitoring SDK into your app and identify the metrics that matter most to your app’s success.
If you’ve used Firebase Remote Config, then you know how it can help you control and optimize your app on the fly. And recent improvements help you better visualize your configuration so you can more easily update your app to drive the outcomes you want, like increasing subscription sign-ups. But what if you have a portfolio of many apps that you want to optimize at the same time?
That was the goal of CrazyLabs, a hypercasual and casual publisher whose games, including Super Stylist - Makeover & Style Fashion Guru, Tie Dye, and Phone Case have been downloaded more than 4 billion times. Their business model relies on identifying potentially high-profit games early on among many applicants and helping them scale. CrazyLabs needed a solution that could help them test up to 30 configurations per title across up to 15 titles at a time in order to increase revenue without decreasing user engagement.
Learn how CrazyLabs used Remote Config and AdMob to optimize monetization at scale for all of their titles in our new case study.
Get ready for a new faster web experience with Firebase. For the longest time you all have asked us to optimize the size of our JavaScript libraries, and we've done just that. We've released brand new beta libraries that are significantly smaller in size. Some are even up to 80% smaller! We've managed to reduce the size all without removing any features from the previous version too!
How did we do this? We did it by embracing the modern web and its new features. We converted our library to take advantage of code elimination features of modern day JavaScript tools like webpack and Rollup. While this change drops size, it did require us to change the library's API for these tools to identify which functionality isn't being used in your app.
This is a breaking change that will require you to update your code. We have released the library to npm under the beta tag, but we will be publishing it to the main tag in the near future. You can get started today and use the compatibility library to make the upgrade easier.
beta
The new API
Take a look at our new beta API. The first thing you might notice is that we've removed all side-effect imports. You know, the import firebase/<service> lines of code, which aren't very clear about what exactly is being imported. Or as webpack succinctly puts it "A "side effect" is defined as code that performs a special behavior when imported, other than exposing one or more exports. An example of this are polyfills, which affect the global scope and usually do not provide an export."
import firebase/<service>
From now on in our API, we explicitly export each function from the package, which makes it clear what you are consuming in your app.
import { initializeApp } from 'firebase/app'; import { getAuth, onAuthStateChanged } from 'firebase/auth'; const firebaseApp = initializeApp({ /* config */ }); const auth = getAuth(); onAuthStateChanged(auth, user => { console.log(user); });
This new API has a lot of familiar functions from the previous one. The main difference is the organization of the code. We've removed all side-effect imports and created individual entry points for each and every package.
import { initializeApp } from 'firebase/app'; import { getFirestore, collection, getDocs } from 'firebase/firestore'; import { getAuth, onAuthStateChanged } from 'firebase/auth'; import { getStorage, uploadBytes } from 'firebase/storage'; import { getRemoteConfig, fetchAndActivate } from 'firebase/remote-config'; import { getRemoteConfig, fetchAndActivate } from 'firebase/remote-config'; import { getDatabase, ref, get } from 'firebase/database'; import { getMessaging, getToken } from 'firebase/messaging'; import { getPerformance } from 'firebase/performance'; import { getAnalytics, logEvent } from 'firebase/analytics';
Modern JavaScript tools like webpack and Rollup discourage the use of side-effect imports. This is because side-effect imports are like an unknown quantity. Module bundlers don't know what they are going to bring in. Having explicit functions to import gives these tools a better understanding of how to build your code.
import { initializeApp } from 'firebase/app'; import { getAuth, onAuthStateChanged, getRedirectResult } from 'firebase/auth'; const firebaseApp = initializeApp({ /* config */ }); const auth = getAuth(); onAuthStateChanged(auth, user => { console.log(user); });
When these tools can understand your code they can eliminate unused parts of a codebase, this is a feature called tree-shaking. This is what makes the new library so much smaller. By reorganizing the Firebase library we can take advantage of tree-shaking and remove all unneeded parts of the library from your app. This size savings we have seen have been significant.
How much smaller is the new library?
Let's get real for a second and talk library size. Firebase has always been a larger library on the web. The web itself is a balance of features and performance and we wanted to make that balance a lot easier for you. This was the biggest reason for us to take on tree shaking. We suspect that no matter what you'll see a sizable drop in your bundle size. However, we're hoping that with specific use cases you'll see significant size reductions.
The two biggest areas of improvement we have seen in our early studies are with the new firebase/firestore/lite package (more on that in a bit!) and firebase/auth. The table below shows a package, the current SDK version size, the current beta version size for a basic use case, and the percentage the SDK is lighter than the current v8 version.
firebase/firestore/lite
firebase/auth
You'll notice that authentication can be up to 72% lighter than before. When using firebase/firestore/lite you can save 84% from the current version of firebase/firestore if you only need one-time reads. This new "import only what you need" method allows you to decide what to include in your bundles and make that features and performance balance much easier.
firebase/firestore
Introducing Firestore Lite
Firestore is such a powerful library because it does so many things behind the scenes that we encourage you all to take for granted. Firestore has a complex caching, realtime streaming, persistent storage, multi-tab offline sync, retries, optimistic concurrency, and so much more. But we heard from you all that sometimes you just need to get a collection, and don't want to include all of Firestore's other features in your site. For those cases we wanted to make Firestore a simple and light solution, so we created a brand new subpackage: firebase/firestore/lite.
import { initializeApp } from 'firebase/app'; import { getFirestore, collection, getDocs } from 'firebase/firestore/lite'; const firebaseApp = initializeApp({ /* config */ }); const db = getFirestore(); const snapshot = await getDocs(collection('cities'));
This sample uses firebase/app and the new firebase/firestore/lite package. You'll notice that calling getDocs() initiates a one-time data read. Firestore Lite allows you to create, read, update, and delete data with Firestore in a much smaller library. Realtime streaming is not included, but you can always switch back to firebase/firestore if that's what you need. If you want to adopt an advanced loading strategy, you can even load firestore/lite for a fast initial page load and lazy load firebase/firestore for progressive enhancement.
firebase/app
getDocs()
firestore/lite
Firestore Lite is significantly smaller. As you saw in the table above, it can be 84% lighter. We know that you Firestore users will find a great fit for this library.
An easier upgrade with our compatibility library
Change is never easy. Our new library provides new benefits but it's hard to go back and rewrite code that already works. To make that process easier, we're also releasing a compatibility library that allows you to port your code piece by piece.
import { initializeApp } from 'firebase/compat/app'; import 'firebase/auth/compat'; import { onAuthStateChanged } from 'firebase/auth'; const firebaseApp = firebase.initializeApp({ /* config */ }); const auth = firebaseApp.auth(); onAuthStateChanged(auth, user => { console.log(user); });
The new modular SDK cannot be used alongside the existing namespace based library, but the compatibility library allows you to use both APIs at the same time. You won't get all of the tree shaking advantages upfront, but once you match the new modular library you can switch off the compatibility library and rake in the savings.
What about framework integrations?
Libraries like AngularFire, ReactFire, and RxFire will be compatible with the new SDK in the near future. We are close to completing them, so hang tight! Track their progress in these issues on GitHub.
Once they have been updated there will be little to no work to move over, as we will update them underneath the hood. However, AngularFire will not initially receive all of the tree shaking benefits since it follows a classical OOP structure. We plan on releasing an API proposal in the near future to optimize for tree shaking and provide an easy path to upgrade as well.
Get started today
The new JavaScript library is available today on npm under the beta tag. We want to hear your feedback! Tell us what you think of the new API and any size savings you've seen. We're excited about the future of this library and the performance benefits it brings.
To learn more about the new library, see our talk at Google I/O. Also check out our upgrade guide for in-depth information about the upgrade process.
First impressions matter to app users. Even the most well-designed apps can fall flat if they don’t consistently deliver a crash-free experience.
Picture one of your app users getting ready to unwind after work. They grab a snack, get comfortable on the couch, and open their favorite gaming app … and it crashes. Or perhaps it freezes every time they’re on the brink of reaching the next level. These unstable experiences can frustrate users and may result in them uninstalling or leaving a scathing review on the app store.
In fact, quality issues are the most common reason for early app deletion. One in five users (19%) will uninstall an app due to technical errors or crashes.1
There are a handful of reasons for app crashes. A user’s device may have low memory or a weak chipset, or it may be running an earlier OS version. Alternatively, the app’s code may be filled with bugs. More importantly, as you add new features and acquire more users on different devices, you’re likely to encounter a wider variety of crashes behind the scenes.
Manually tracking, organizing, and fixing crashes can be a complex and time-consuming challenge. And even if you collect every bit of crash data, it can still be unclear what’s causing your app to crash or which errors are impacting the most users. That’s where having the right crash reporting tools makes all the difference.
Continually improving your app and launching new features is one of the best ways to increase retention and engage new and existing users. However, as your user base grows, splitting your time between releasing new features and monitoring the stability of new releases becomes a bit of a conundrum.
Real-time crash reporting in Firebase Crashlytics allows you to quickly triage and troubleshoot any bugs in your app by gathering and grouping crashes based on where they occurred in your app’s code. Groups of crashes are listed in order of frequency and degree of impact on users, making it easier to identify which issues to tackle and providing you with more time to build features that keep users engaged.
Crash report data displayed in the Firebase Crashlytics dashboard
To go even deeper into your crash data, you can enable BigQuery streaming export to identify prevalent issues and understand trends over time — such as which OS versions or specific devices are causing the most crashes. This helps you visualize your crash data and monitor issues that trigger alerts and custom workflows. Enabling BigQuery streaming also gives you the ability to analyze your data with BigQuery SQL, export it to another cloud provider, and use Google Data Studio to create custom dashboards and visualizations of crash trends.
Crashlytics integrated with BigQuery
For an app like Spotify — with more than 65 teams maintaining millions of lines of code per platform and launching new updates every week — moving fast and at scale is essential. To reduce stress on its development team before each launch, Spotify switched from manually tracking crashes every day to automating their release process using Crashlytics, primarily with BigQuery. Rather than having the team’s release manager on call to monitor each crash, Spotify now uses Crashlytics to track crashes for alpha and beta builds, set rules for incoming tickets, and assign tickets to the right teams.
Deliveroo, a food delivery company based in the U.K., similarly adopted Crashlytics and BigQuery to get ahead of crashes before they reach a certain threshold while tracking and analyzing performance data of each new release in real time. With the ability to create customized reports and separate errors, the development team drastically cut down on the time spent troubleshooting and reproducing app issues — and crash-free sessions increased from 99.35% to more than 99.7%.
Crashes don’t just turn away your existing app users — negative app reviews caused by an unstable session can also impact your ability to acquire new users. That’s why it’s crucial to know when and where crashes are happening.
Crashlytics velocity alerts notify you when a particular crash starts spiking so you can respond before the bug impacts more users. Velocity alerts are also configurable, giving you the power to set thresholds that determine when alerts should fire based on the percentage of user sessions being affected.
For instance, velocity alerts can detect major bugs during the rollout of a new release of your app or quickly alert you if there’s an issue impacting a large percentage of users. Velocity alerts will send an email or message on Slack, Jira, or PagerDuty, depending on which third-party integration you have enabled with your project.
Velocity alert settings in the Firebase Console
That’s exactly how Swiggy — one of India’s largest food delivery services — simultaneously monitors every app issue while focusing on the most significant ones first. Swiggy’s development team connected Crashlytics velocity alerts to PagerDuty and Jira to notify its on-call engineer whenever critical crashes reach a certain threshold. This allowed Swiggy to keep shipping fast with the confidence that they will be notified about high-priority crashes and low-priority crashes in the right manner.
Quickly identifying prevalent crashes is just one piece of the puzzle. By getting to the root cause, you can mitigate risk and avoid frustrating your app users by ensuring those crashes don’t happen again.
Crashlytics custom logs and keys record the events a user experienced during their session by tracking the state and sequence of their app. This gives you an actionable snapshot of what the user was doing leading up to the moment your app crashed. You can also define custom keys such as “installation_source”, “network,” and “language” to pinpoint exactly what happened before each crash — like whether a user installed your app on the Play Store or if they were connected to Wi-Fi — and reduce the time it takes to reproduce it.
And by using Crashlytics with Google Analytics, you can automatically capture predefined Google Analytics events — known as breadcrumbs — which enhances the data captured with custom logs and provides more detailed information on what caused a crash.
Breadcrumbs in Google Analytics
For mobile game publishers like Tapps Games, delivering a stable and immersive experience is crucial for keeping gamers engaged. Previously, Tapps would manually search through user reviews for negative feedback and then try to reproduce the crashes that users described. With Crashlytics' velocity alerts, the team was immediately notified when severe crashes were on the rise. After digging into the data, they realized an update to their Vlogger Go Viral game's video creation process and a simultaneous community player event was leading to consistent crashes.
Tapps Games’ development team jumped on a fix that helped boost their Google Play store rating from 3.9 to 4.7 and increased their crash-free users from 94.6% to 99.8%.
To grow your audience, keep users engaged, and spark positive reviews and recommendations, app stability needs to be a key focus area. Installing the Firebase Crashlytics SDK in your app gives you the tools and information you need to stay on top of critical issues.
In the third and final series of our guide, we’ll spotlight a set of tools you can use alongside Firebase Crashlytics to understand how your app is performing from a user's point of view.
Sources