Even if your mobile app has been downloaded by millions of users worldwide, making it profitable in the long run is a tricky science. Most apps rely on a mix of ads and in-app purchases (IAP) to make money. The challenge is finding the right balance to maximize both revenue streams while ensuring an engaging experience for every user.
But determining your overall ad monetization strategy without negatively impacting in-app purchases isn’t a one-time effort. Between competition from other apps, changing user behavior, and evolving ad formats, you need to continually assess and experiment with your strategy to find an optimal mix. Doing so can keep users from dropping off from your app and even drive a 25% bump in total ads revenue, as mobile games publisher Pomelo Games discovered.
To tackle this challenge, you need a simple way to test and validate changes to your ads strategy in one place. And ideally, you'll want to gauge the impact of any changes on a small subset of users before rolling them out to your entire user base.
Linking AdMob, Firebase, and Google Analytics provides a streamlined solution to experiment with ads, and make smarter decisions based on app and ad performance insights. Here’s what each tool brings to the table:
Firebase Remote Config allows you to change the appearance and behavior of your app dynamically for any target audience — with no need to release an app update. For instance, you could design a new branding style for users in a certain country or region or change your app's color theme to match a seasonal promotion. You can also provide different app ad experiences, customized to different users in your app.
From there, you can use Firebase A/B Testing with Remote Config to run product and marketing experiments with variants of your app and analyze the results. This helps you make informed decisions about what’s working and whether your changes should be rolled out to more users.
Let’s say you launched a hit space shooter game and want to figure out what type of gameplay keeps users engaged — an easier version with fewer aliens to fight, or a more challenging version with fewer power-ups and a lot more monsters.
Using Remote Config, you build in the framework that enables you to add more challenging elements to your game without having to re-code and publish an entirely new version. Then, you can set up an A/B test that deploys these challenging elements to a small group of users, like your expert-level gaming audience. As part of setting up the A/B test, you choose primary and secondary metrics to optimize for, such as retention rate or total estimated revenue, and then you watch how the more challenging variant performs compared to the easier version.
And thanks to Firebase’s integration with Google Analytics, the actions that users are taking inside the app as a result of your experiments are factored into determining how well a variant performs.
Applied to your ads strategy, this testing framework using Firebase allows you to optimize for goals, like total ads revenue, while also tracking the impact on secondary metrics, like overall app monetization and user retention.
For instance, you might want to figure out if you can earn more ads revenue by adjusting the frequency capping without a drop in user retention. Using AdMob, you can create two ad units that vary in how often they’re shown to the user — say, one ad every 20 minutes versus one ad every five minutes. You can then use Remote Config and A/B testing to evaluate how these two different ad frequencies impact your ad revenue. You can also add secondary metrics to watch during the A/B test, like user retention and IAP revenue.
Or perhaps you’ve noticed a steady drop in ad clicks as people spend more time in your game and suspect it’s related to ad formats. For this case, you can experiment with the various ad formats in AdMob and A/B test these variants on a small number of users who spend more time in your game (an audience determined by Google Analytics). Then, when your A/B test determines which ad format increases ad clicks, you can roll out the new format more widely.
Whether you want to experiment with frequency capping to increase revenue or serve ads to a specific audience, linking AdMob with Firebase and Google Analytics leads to smarter, data-driven decisions. With insights about which users are most likely to spend money in your app, you can even fine-tune who sees an ad versus who’s encouraged to make a purchase instead.
Mobile game publishers around the world have successfully used these tools to optimize their ads and in-app purchases strategies without hindering the player experience. After hearing plenty of positive user feedback — including about the ads themselves — Four Thirty Three Inc. and Pomelo Games (mentioned earlier) were inspired to transform their entire business model, with Firebase tools at the core.
You can watch this session from Firebase Summit and learn more about features you can unlock by linking Firebase, Google Analytics, and AdMob.
Last year we announced our investment in making Firebase libraries more Kotlin-friendly with Firebase Kotlin extension (KTX) libraries. Since then we have seen increasing interest for Kotlin within the Firebase community. In this blog post, we’ll go over how developing with Kotlin can lead to fewer crashes; and how you can monitor your app’s stability with Firebase Crashlytics once your app has been released.
Users expect to have a seamless experience every time they use your app. Crashes can cause churn and poor reviews, and quality issues are one of the main causes of early app deletion. Android apps built with Kotlin have 20% fewer crashes, which is one of the reasons that over 70% of the Top 1000 apps on the Play store have adopted Kotlin. Using Kotlin allows you to reduce the chances of getting null pointer exceptions, which are the #1 type of crashes on Google Play.
Furthermore Kotlin extension libraries let you write cleaner code by reducing boilerplate and making it easier to take advantage of advanced Kotlin language features even when using libraries originally written in Java.
In addition to our Firebase KTX libraries, you can also use the coroutines Kotlin extension libraries by Jetbrains to write safer async code with Kotlin and Firebase:
dependencies { // Coroutines implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' // Coroutines extensions for the Tasks API implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.3.9' // Firestore Kotlin extensions implementation 'com.google.firebase:firebase-firestore-ktx:22.0.2' }
Consider this code to fetch a document from Firestore. This code uses the Firebase Android SDK and the Play services Tasks library, both of which are Java libraries:
fun getUser() { val query = FirebaseFirestore.getInstance() .collection("users").document("user123") // query.get() returns a Task, we attach a callback to get the result query.get().addOnSuccessListener { snap -> val user = snap.toObject(User::class.java) } }
By using the Kotlin extension libraries above we can make this code simpler, safer, and easier to read:
suspend fun getUser() { // Firebase.firestore is a convenient syntax from the firestore-ktx library val query = Firebase.firestore .collection("users").document("user123") // The kotlinx-coroutines-play-services library allows us to "await" the // result of a Task and avoid callbacks, which simplifies our control flow val snap = query.get().await() // The .toObject<T> function from the firestore-ktx library uses Kotlin's support // for advanced generics to avoid the need to pass a Class object val user = snap.toObject<User>() }
Example provided by Firebase GDE Rosario Pereira Fernandes
Once you’ve developed and released your app, Firebase Crashlytics helps you improve and monitor your app stability. With Crashlytics you can track, prioritize and fix stability issues that erode app quality, in real-time. For instance, custom logs and keys in Crashlytics provides you with information on the specific state of your app leading up to a crash and gives context on why a crash occurred. With this level of in-depth insight, you can uncover the root causes of crashes more quickly before they affect a large number of your users.
For further analysis of your Crashlytics data and to segment your user data, you can also export all your crash data to BigQuery in real-time. For example, you can determine emerging crashes in new code, or see the top crash issues for the day to help you prioritize and fix them faster. You can also use our Data Studio template to easily visualize this data with custom dashboards. Data Studio dashboards are easy to collaborate on and share so your team can work more efficiently; even your team members who aren't comfortable with SQL can easily work around BigQuery data sets.
These are just a few examples of the ways you can improve your app stability with Firebase, Kotlin Extensions and Crashlytics. It’s easy to get started with Crashlytics and Firebase Kotlin Extension libraries, and as always if you need help please feel free to reach out to us through our Community Slack.
Happy developing!
A few months ago, we released Firestore for Games into open alpha. Thanks to all of your feedback, today, we're happy to announce that Cloud Firestore for Games is now publicly available in beta for C++ and Unity developers.
Firestore is a new performant and scalable serverless database option from Firebase for all your game development needs. It can help you add guilds to your latest mobile game, build a backend for your next big turn-based game, or add realtime chat. It’s also a key component of Firebase Extensions like Translate Text and Trigger Email, making it easier than ever to deploy pre-built complex workflows to your games.
Cloud Firestore is Google’s next generation cloud NoSQL database. It’s fast, reliable, and ready to scale for whatever workload you send its way. For the past two years it’s been generally available for the Web, iOS, and Android, and now it’s available for game developers as well.
Cloud Firestore exists alongside our existing Realtime Database. We’ll continue to support Realtime Database because it still works great for when you need to share data quickly with lots of players in near realtime. With Firestore you get more advanced queries on your data, 99.999% guaranteed uptime, and support for up to a million concurrent players -- all whilst remaining fast enough for many of your gaming backend needs. If you need more help deciding which database is right for you, check out this helpful guide.
Even though Firestore has been generally available for some time, the existing SDKs were built with the workflows and tools favored by app and web developers. Although game developers working in languages like JavaScript, Kotlin, and Swift would have no problem adopting the existing development kits, you would’ve had to jump through hoops to access them from Unity or C++. However, here at Firebase and Google, we want to make it easy for game developers to build, release, and operate games. So, we've built SDKs that bring game developers the same levels of convenience that app developers enjoy.
The Beta tag means that we believe that the Firestore SDKs for Unity and C++ are now stable enough that game developers can confidently use them in shipping games. Bugs and small API tweaks may crop up here and there as more developers pick it up, but Firestore is now a viable option when starting new game projects.
A big improvement that alpha testers might notice is that the new libraries have full feature parity with the platform specific Firestore SDKs. This includes many features alpha testers have asked for, such as OnSnapshotsInSync and support for the Blob data type. All transforms (like incrementing values) and query types (like "array-contains-any") are now implemented as well. We’ve also worked to make Firestore more consistent with the other Unity Firebase SDKs by ensuring that events fire on the main thread and adding more consistency to error reporting.
OnSnapshotsInSync
Since we’ve seen that many game developers tend to target multiple platforms with a single codebase, we’ve ensured that every feature in Firestore SDK C++ SDK works identically on iOS, Android, Windows, Mac, and Linux. This means that you can develop your game logic on a desktop computer with access to the entire Firestore for games feature set, and remain confident that it will continue to function on your target device. We've also fully opened sourced the C++ SDK so you can easily build, debug, and port your code to wherever you need.
This Firestore beta, like the alpha, ships with the standard Firebase C++ and Unity SDKs. To use it, simply ensure you’re using the latest Firebase SDK either by downloading the C++ zip or the Unity zip. Remember, if you come across any bugs, report them to us through our support channel or on the C++ or Unity issue pages.
Firebase Extensions are a convenient way to add new functionality to your app with the click of a button. They are pre-packaged solutions for common problems that you can easily add to your Firebase app. Extensions are based on Firebase and Google Cloud products that you already know and use.
On the Firebase Extensions page, you will find a collection of official extensions for features that developers find themselves in need of regularly, such as resizing images, sending emails based on the contents of Firestore documents, translating text, shortening URLs, and more. Most of these extensions have been built and tested by the Firebase team, and follow best practices. In addition, we have teamed up with partners like Stripe to bring you extensions for processing payments and sending invoices.
Installing extensions is easy via the Firebase console or the Firebase command line interface.
To allow us to get more feedback from you and to better understand which use cases and extension features people are most interested in, we are launching a new type of extensions: Experimental Extensions.
These are fully functional extensions that we think you'll find useful, but they haven't yet gone through the same amount of testing and polish as the official published extensions.
The following extensions are built by our engineers looking for feedback from the community.
To install an experimental extension, navigate to the extension's README file in the Firebase Experimental Extensions repo on GitHub, and then click on the Install on Firebase button. This will take you to the Firebase Console, where you can then select the project you'd like to install this extension in.
You can also install extensions via the command line. To do so, make sure you've got the Firebase Command Line tools installed, then run the following command:
$ firebase ext:install firestore-shorten-urls-dynamic-links --project=(your project ID)
This command will install the Shorten URLs with Dynamic Links experimental extension in your project.
We love to hear your feedback, and we're looking forward to seeing what you will build using the new experimental extensions! Use the GitHub issue tracker of the experimental extensions repository to leave feedback.
If you'd like to submit PRs to improve an experimental extension, you will need access to the extension authoring tools. To learn more about this, join our Alpha program.
From conversations with you, we know you're excited to build and share your own extensions.
To share extensions with other developers, you need to become an Extension Publisher. Register as a publisher by joining the Firebase Alpha program, and indicate you're interested in building Community Extensions in the comments field. You can then publish your extensions under your publisher ID.
Your extension code will live in Firebase, so other alpha group members can install your extension directly from the command line.
At the moment, Community Extensions can only be shared with members of the Firebase Alpha program, but we're working hard to let you share your extensions publicly.
We're excited to share these two new kinds of extensions with you, and we can't wait to see what you're going to build!
We made a comic about Crashlytics—the first ever comic created by Firebase! The Great Crash Detective investigates a mystery case of a new crash in her mobile application. Does she solve it, or let her product manager down? Read it to find out!
The inspiration for this comic all started with a customer interview. On the Crashlytics team, we love talking to developers about how they're using our product. So naturally when a developer reached out to us to find out if there were ways to better understand the events leading up to a crash, we jumped on the task. Crashlytics allows you to add custom logs to your crash data. However, this developer needed help searching through these custom logs to find what events these crashes were occurring within.
In August of 2018, Crashlytics released the ability to export your data to BigQuery and enhanced it last year by making it possible to export data in realtime. One of the useful things about exporting your crashes to BigQuery is that you can freely investigate the underlying crashes occurring in your app.
We asked the developer who was interested in searching their custom logs if they had considered exporting their data to BigQuery, they explained that they didn't have bandwidth to learn how to use SQL.
Learning SQL is a continuous process
This was a huge opportunity for us to communicate with customers the alternatives to using SQL (though, we also think exploring your BigQuery data using SQL is pretty great!). For example, Google Data Studio lets you visualize your BigQuery data quickly and easily. You can use our template to customize a report to address your specific needs.
The developer was able to use a Google Data Studio report to visualize their crash reports and analyze their data quickly and easily. They had already followed the steps to enable BigQuery export and the instructions to attach a datasource to our Data Studio Template to create a report, the steps to adding a custom log filter were quick and easy:
First, they navigated to the "Crashes by File" page of the report.
Next, they clicked Insert -> Advanced Filter.
Afterwards, they placed the filter in an empty spot in the report.
Finally, they edited the control field for this filter. On the data pane (to the right of the report), they changed the control field to "logs.message".
That's all that was needed to search a Crashlytics crash dataset for the occurrence of custom log events (here's an example template of the above steps). Searching by other fields within Crashlytics crashes, such as analytics breadcrumbs, is as easy as changing the control field for that filter.
We'd love to hear your feedback. Should we do more Firebase comics? Are you interested in what happens next for the Great Crash Detective? Do you have any feedback about using Crashlytics with BigQuery and Data Studio? Feel free to reach out to us on Twitter or come hang out with us in the Firebase Community Slack channel.
Did we make a comic about Crashlytics, or was it all a dream?
This comic was created by Luke Kruger-Howard, an Ignatz-nominated comic artist, in collaboration with myself and other engineers and product folks from the Crashlytics team.
p.s. Why did the horse's app crash?
Because the app was unstable.