As the Product Manager of Firebase Remote Config, a product that helps you modify your app without deploying a new version, I spend a lot of time talking to our customers, and one of the most common requests I hear is, "Can I get rid of the Remote Config cache and fetch new values right away?"
While we can't get rid of the cache entirely -- caching ensures that the Remote Config service stays up and running, free of charge, no matter how many millions of users you have -- thanks to some new features we've added to Cloud Functions for Firebase, you can now ensure that your users always get fresh Remote Config values whenever they open your app!
Before we get into our solution, let me explain why the problem isn't as bad as you think, by looking at a typical app that has a Remote Config cache time set to 4 hours. You might think that, if this app developer publishes new Remote Config values, most of their users won't see these new values until several hours later.
But the fact is, the vast majority of their users will see the new Remote Config results as soon as they run the app! Remember, the way the cache works is that it looks at the last time Remote Config successfully fetched data. So anybody who last opened their app more than 4 hours ago will retrieve fresh data.
To put it another way, if your user opens up your app at 7:00 pm, you push out new values at midnight, and then they open up your app again at 12:15 am, Remote Config will fetch your new values from the server. Sure, it's only been 15 minutes since you published your values, but their cache is over 5 hours old, so Remote Config will fetch fresh values.
Nevertheless, I understand that it's really important for many of you to push out new changes to all of your users right away. Maybe you want feature flags to be disabled quickly. Or, maybe you have time-sensitive values, like marketing campaigns or a flash sale, in which case it would be awkward for your users to still see messaging for a sale that's no longer running.
Fortunately, we've built a new integration with Cloud Functions for Firebase that will make it easier for you to build custom behavior based on events that happen in Remote Config. Specifically, you can now use new triggers to write code that runs whenever your team publishes Remote Config values -- whether that's through the Firebase Console or the REST API.
There are a number of ways you can use these Remote Config triggers. One significant way is to use them to notify all of your apps as soon as a new set of values get published on Remote Config.
If you're interested in learning how to implement this feature, here's a high level overview of the process:
For more information, check out the solutions guide in our documentation. This guide contains all of the code samples you'll need, both in your Cloud Function, and on the client.
You might be wondering why you can't just a) set your Remote Config cache to 0 all the time, or b) have your clients go and always retrieve the new Remote Config values as soon as they receive the notification.
The answer is that Remote Config still needs to make sure the service is usable (and free) by all apps, and we've set up both client and server-side throttles to make sure that no single app accidentally abuses the service. By sticking with the default caching time when there's no local flag indicating that there's new config available, you can avoid any client-side throttles. Your app will have a faster start-up time, too, by avoiding unnecessary network calls.
By waiting until your client goes into the foreground to fetch these new values, you avoid any server-side throttles. You'll also avoid having your clients make unnecessary network calls in the background, which means your app uses less data overall, which makes your users happier, particularly in areas of the world where data usage is expensive.
By making sure your apps are still well-behaved, you can still get the freshest possible Remote Config values while avoiding any throttles that might be applied to your app. Please consult our caching & throttling documentation for further information on this topic.
One other advantage of using this system is that if your app in the foreground when it receives this notification, you can immediately act on this information - perhaps by fetching the new Remote Config data and prompting the user to refresh their screen. So those of you who were actively polling the Remote Config service while your app was in the foreground no longer need to resort to any of those network calls anymore.
Of course, this isn't the only use for Remote Config triggers and Cloud Functions - just one of the most requested, for sure! A number of developers also want to know when new Remote Config values have been pushed to the Firebase console, and you can use Cloud Functions to send off an email to your team or push a message in a Slack channel.
You could also use Cloud Functions to keep different projects in sync. For instance, you could use a cloud function to copy a set of Remote Config values from your production project to your development or testing project.
If you're interested in giving this new approach a try, we encourage you to read over the full documentation in the solutions guide. As always, if you have other questions about Remote Config or other feature requests, we're happy to hear your feedback. Please reach out to us in the Firebase Talk group, or on Stack Overflow.
If you're building or looking to build a visual app, you'll love ML Kit's new face contour detection. With ML Kit, you can take advantage of many common Machine Learning (ML) use-cases, such as detecting faces using computer vision. Need to know where to put a hat on a head in a photo? Want to place a pair of glasses over the eyes? Or maybe just a monocle over the left eye. It's all possible with ML Kit's face detection. In this post we'll cover the new face contour feature that allows you to build better visual apps on both Android or iOS.
With just a few configuration options you can now detect detailed contours of a face. Contours are a set of over 100 points that outline the face and common features such as the eyes, nose and mouth. You can see them in the image below. Note that as the subject raises his eyebrows, the contour dots move to match it. These points are how advanced camera apps set creative filters and artistic lenses over a user's face.
Setting up the face detector to detect these points only takes a few lines of code.
lazy var vision = Vision.vision() let options = VisionFaceDetectorOptions() options.contourMode = .all let faceDetector = vision.faceDetector(options: options)
The contour points can update in realtime as well. To achieve an ideal frame rate the face detector is configured with the fast mode by default.
fast
When you're ready to detect points in a face, send an image or a buffer to ML Kit for processing.
faceDetector.process(visionImage) { faces, error in guard error == nil, let faces = faces, !faces.isEmpty else { return } for face in faces { if let faceContour = face.contour(ofType: .face) { for point in faceContour.points { print(point.x) // the x coordinate print(point.y) // the y coordinate } } }
ML Kit will then give you an array of points that are the x and y coordinates of the contours in the same scale as the image.
The face detector can also detect landmarks within faces. A landmark is just an umbrella term for facial features like your nose, eyes, ears, and mouth. We've dramatically improved its performance since launching ML Kit at I/O!
To detect landmarks configure the face detector with the landmarkMode option:
landmarkMode
lazy var vision = Vision.vision() let options = VisionFaceDetectorOptions() options.landmarkMode = .all let faceDetector = vision.faceDetector(options: options)
Then pass an image into the detector to receive and process the coordinates of the detected landmarks.
faceDetector.process(visionImage) { faces, error in guard error == nil, let faces = faces, !faces.isEmpty else { return } for face in faces { // check for the presence of a left eye if let leftEye = face.landmark(ofType: .leftEye) { // TODO: put a monocle over the eye [monocle emoji] print(leftEye.position.x) // the x coordinate print(leftEye.position.y) // the y coordinate } } }
Hopefully these new features can empower you to easily build smarter features into your visual apps. Check out our docs for iOS or Android to learn all about face detection with ML Kit. Happy building!
Here at Firebase, we believe that apps improve the way people live, work, learn, and socialize. That's why our mission is to make app development as easy as possible by giving you a platform that solves key challenges across the app lifecycle. Whether you're an up-and-coming startup or a well-established enterprise, Firebase can help you build your app, improve its quality, and grow your business.
It's exciting to evolve Firebase alongside our passionate community. Right now, over 1.5 million apps are actively using Firebase every month. We love hearing your stories; they inspire us to keep making Firebase even better so you can continue to succeed. One story we heard recently is from Hotstar, India's largest entertainment app with over 150 million monthly active users around the world.
A few months ago, the Hotstar team safely rolled out new features to their video watch screen during a major live-streaming sports event. These changes, along with updates to their onboarding flow, increased user engagement by 38%! Impressively, by using a combination of Firebase products, Hotstar was able to do this without disrupting users, sacrificing stability or releasing a new build.
Learn more about their story here:
Today, we're hosting the third annual Firebase Summit in Prague to meet many more members of our developer community and learn about the great things they're building. All sessions will be posted to our YouTube channel or you can read on to learn about all the exciting new updates we're announcing today!
We've been working hard to make it easier for sophisticated app development teams to use Firebase. Today, we're excited to share that we'll be adding support for Firebase to our Google Cloud Platform (GCP) support packages, available in beta by the end of this year.
If you already have a paid GCP support package, our beta will let you get your Firebase questions answered through the GCP support channel - at no additional charge. When this new support graduates to general availability, it will include target response times, technical account management (for enterprise tier), and more. You can learn more about GCP support here.
If you're planning to stick with Firebase's free support, don't worry - we don't plan to change anything about our existing support model. Please continue to reach out to our friendly support team for help as needed.
In addition to Cloud support, we've made improvements to Firebase across the board. More below!
Manage projects with ease via Firebase Management API
We've worked hard to open access to our server-side APIs, so that you can easily integrate Firebase services with your existing systems. Today we're releasing the Firebase Management API, a REST API that allows you to create and manage projects and apps programmatically. Now, you can create and destroy Firebase environments as part of your existing developer workflow.
The Management API is also enabling partners to build awesome new experiences. We're thrilled to share that you can now deploy to Firebase Hosting directly from within StackBlitz and Glitch, two web-based IDEs. Their platforms will now automatically detect when you are creating a Firebase app and allow you to deploy to Firebase Hosting with the click of a button, without ever leaving their platforms.
What's especially cool is that this isn't just for partners. This is a new, extensible API and we're very excited to see what you build with it. You can learn more and get started here.
Enhanced face detection with ML Kit
Launched at Google I/O in May, ML Kit makes machine learning easy and accessible for all app developers, regardless of your experience with ML. If you're new to the space you can use ML Kit's out-of-the-box APIs, like text recognition or face detection, or if you're more experienced you can bring your own custom TensorFlow Lite models and serve them through Firebase.
Today, we're expanding on the face detection API with the beta launch of face contours, allowing you to detect 100+ detailed points in and around a user's face. The face contours functionality empowers apps to easily overlay masks or accessories on facial features with high fidelity and accurate positioning, or add beautification elements, like skin smoothing or coloration. See our docs to learn more!
Increased confidence in deployment with Cloud Firestore
In the past, we've heard feedback that testing can be tricky on Firebase. For example, it's sometimes hard to set the right rules to ensure your apps are secure. To help with this problem, we're releasing local emulators for Cloud Firestore and the Realtime Database. These emulators let you develop and test locally, and can be built into your continuous integration workflow so you can deploy with more confidence and peace of mind. Learn more about the emulator here.
Propagate Remote Config updates in near real time + integration with Cloud Functions
Developers love using Remote Config because it gives them the ability to modify their app, customize the UI, or release a new feature without deploying a new version that could disrupt users. But, there was no easy way of knowing when an app's Remote Config was updated! You had to fetch updates from Remote Config every few hours to ensure your users always saw the latest changes in their app.
Today, we're happy to announce that Remote Config now integrates with Cloud Functions & Firebase Cloud Messaging so you can notify your apps in near real time when you publish (or rollback) a new config. This reduces the set-up complexity of Remote Config and uses less bandwidth on devices because apps only need to fetch when a new config is available.
Additionally, Remote Config can now trigger developer-defined functions when you publish or rollback your config. This way, you can keep different Remote Config projects in sync (for development/staging/production environment workflows), as well as send Slack messages to your team when a new config is published. To learn more, visit our docs!
From our early access partner eBay:
"The combination of the Cloud Functions with the Firebase Remote Config REST API has allowed my distributed team at eBay to be instantly notified of any changes to our application's configuration. Using these tools to create a function which pushes changes to Slack ensures everybody who needs to know about a configuration change has that information immediately."
- Jake Hall, eBay Classifieds Group Mobile Architect
Test Lab for iOS graduates into general availability
At Google I/O, we also launched the beta availability of Firebase Test Lab for iOS. Over the last several months, we've expanded the iOS device farm, added support for iOS 12 as well as for older iOS versions, and integrated the UI for iOS into the Firebase console. With these updates, we are graduating Test Lab for iOS out of beta and into general availability. Learn more and get started with Test Lab today!
Performance Monitoring: Sessions insights and issues management
Even if you run thorough tests throughout your development lifecycle, bugs and performance issues will pop up in your production app from time to time. Performance Monitoring gives you insight into these issues and automatically surfaces the most critical issues in a given trace instance (i.e. a particular app start or checkout flow). Now, you can dive into an individual trace session to see exactly what was going on when a performance issue occurred.
For example, in the following dashboard, you could see that CPU usage spiked after the app fetches and renders a product image, which tells you the specific part of code to investigate.
With all the data and issues that Performance Monitoring surfaces, it can be hard to prioritize your efforts. That's why we're also launching the ability to "mute", "close", and "reopen" issues in your console. Muting temporarily silences the issue, so you can concentrate on other work, until you're ready to tackle it. Marking an issue as closed indicates that it's been solved, but Firebase will notify you if it occurs again.
Learn more about session insights and issues management here.
Crashlytics is now integrated with PagerDuty
App performance and stability issues can occur anytime. To help you stay on top of stability, even when you're away from your desk, we're introducing a Firebase Crashlytics stability digest email and a new integration with PagerDuty. The stability digest highlights emerging issues that could become problematic in the future, while the PagerDuty integration allows you to alert your team about a high impact crash, any time of day. To connect Crashlytics with PagerDuty, follow the steps here.
Do more with your data with BigQuery + Data Studio
Earlier this year, we integrated Crashlytics with BigQuery so you can run deeper analysis on your crash data. To help you get started in BigQuery, we've put together a Data Studio template, so you can quickly produce a shareable report. You can preview the template with mock data, and then customize the report to suit your needs. Learn more here.
Predictions graduates out of beta into general availability
Last year at the Firebase Summit, we introduced you to Firebase Predictions. Predictions applies Google's machine learning to your app analytics data to create user segments based on predicted behavior. Without requiring anyone on your app team to have ML expertise, Predictions give you insight into which segments of users are likely to churn or spend (or complete another conversion event) so you can make informed product decisions. This year, we're excited to announce that Predictions is graduating out of beta and into general availability with a host of new features designed to make Predictions more useful.
Wondering what goes go into any given prediction? We added a new details page that shows you what factors the ML model considered (like events, device, user data, etc.) to make that prediction. We also now expose performance metrics for each prediction, letting you see how the prediction has performed historically against actual user behavior, so you can better calibrate your risk tolerance level. And, if you want to do a deeper analysis of prediction data or use it in third party services, you can export your complete prediction dataset to BigQuery.
Check out our docs to learn more!
Reach users more effectively with dynamic audiences in Google Analytics
Google Analytics for Firebase has always given you the ability to segment your users into audiences based on events, device type, and other dimensions. Now, we're enhancing the audience builder with a few major updates: dynamic audience evaluation, audience exclusion, and membership duration.
First, audiences are now dynamic by default, meaning that Firebase will pull in new users that meet your criteria and automatically remove users that no longer meet your criteria. If, for example, you set up an audience of users who are on level 5 in your game, as users beat the level and move on to level 6, they will automatically be removed from the audience. Conversely, once users advance to level 5 they will automatically be added to the level 5 audience you've established.
Secondly, you can refine your audience by adding exclusion criteria using and/or statements which enable you to create audiences like "users that have added to their shopping cart but not made a purchase".
Finally, audiences can now include a membership duration, allowing you to ensure that your audiences stay fresh. This enables you to target users who have completed an action within a specific time period, e.g. "made a purchase within the past two weeks".
Dynamic audiences allow you to reach your users more effectively with relevant messaging and a more personalized app experience. Learn more and get started with dynamic audiences here.
Run automatically recurring campaigns with Cloud Messaging
Once you've defined your user segments using Analytics or Predictions, you can use Firebase Cloud Messaging (FCM) to send notifications to latent users to bring them back into your app. We've redesigned the notifications console to support more sophisticated campaigns. This new UI gives you the power to set up recurring notification campaigns that automatically send messages to new users as they meet the targeting criteria. Previously, you could only schedule one-time sends.
Additionally, the new notifications UI allows you to easily target users based on the date of their first session or the number of days since they last opened an app. And last but not least, we've updated the campaign results view so you can track the effectiveness of recurring notification campaigns day-by-day.
Check out the new UI on your console!
We're excited about all the updates to Firebase that we've announced today. As we continue to grow and enhance the platform, we'd love to have your feedback. Join our Alpha program to get a sneak peek of what we're building next, share your thoughts with us, and shape the future of Firebase.
If you weren't able to join us in person in Prague, all of our sessions are recorded and posted to our YouTube channel. Thanks for being a part of our community and happy building!
In this edition: Write test-driven Cloud Functions, HIPAA compliance with Firebase Realtime Database, Swifty Firebase, Building a CRUD Ionic app with Cloud Firestore
Hey, Firebase developers! I recently reached out on Twitter to ask for your suggestions for your favorite Firebase tutorials, and was blown away by the responses! I'm amazed at all the creative ways you are using Firebase products. Here are just a few of the tutorials that I've been checking out lately.
Author: Chris Esplin
In the latest tutorial from Google Developer Expert Chris Esplin, see how to write test-driven Cloud Functions using Jest. Test-driven development (TDD) is a software development process that repeats a short development cycle: requirements are made into test cases, then the software is improved to pass the new tests. As someone who tends to test functions in production, I highly recommend you check out this blog to find a much better method!
Author: David Szabo
The Health Insurance Portability and Accountability Act (HIPAA) is U.S. legislation that provides data privacy and security provisions for safeguarding medical information. Applications that handle certain types of health information have to comply with these regulations, so adhering to these standards is essential for developers who wish to distribute health apps in the United States. Lots of developers have asked me questions about Firebase and HIPAA, so I was super excited to see this tutorial, which shows how to use encryption to make a HIPAA-compliant chat app.
Author: Morten Bek Ditlevsen
As a lover of all things Firebase and iOS, I just had to include a Swift tutorial! Morten does some Swifty magic to resolve some of the common stumbling blocks of using Swift with the Realtime Database. In the first article of the series, you see how to implement support for Codable types in Firebase, allowing you to go from this:
Codable
ref.observeSingleEvent(of: .value) { snapshot in guard snapshot.exists() else { /* HANDLE ERROR */ } guard let value = snapshot.value else { /* HANDLE ERROR */ } guard let product = Product(usingMyCustomJSONConversion: value) else { /* HANDLE ERROR */ } } let json: Any = product.myCustomJSONEncoding() ref.setValue(json)
to this:
struct Product: Decodable { ... } ref.observeSingleEvent(of: .value) { (result: DecodeResult<Product>) -> Void in // Use result or handle error } try ref.setValue(product)
Author: Nick Patrick, Radar.io
Radar is a toolkit that removes a number of the challenges involved in location context and tracking, and makes it super easy to perform tasks like knowing when a user enters or exits a known public place or custom geofence.
Nick's tutorial shows you how to use Radar's webhooks to trigger a Cloud Function for Firebase. In this case, it's sending a notification when a user visits their favorite coffee shop, but if you're building any kind of location-based app, you'll find lots of possibilities to apply what you learn!
Author: Jorge Vergara, JAVEBRATT
In this tutorial, you'll find step-by-step instructions for implementing an Ionic application with Cloud Firestore. If you use Angular and are new to Firebase, this tutorial will be a great resource for you!
---
Thanks to everyone who took the time to send me your suggestions! And if you don't see your recommended tutorial here, never fear! I couldn't fit all of the amazing recommendations here, so stay tuned for future blog posts. If these tutorials have inspired to build something with Firebase, let me know! You can find me on Twitter at @ThatJenPerson. I can't wait to see what you build!
In the "Notifying your users with FCM" blog post, we shared guidance on using FCM in modern Android with regard to all the power management features. Following on that, let's look at the common workflow of FCM messages -- notification messages and data messages, and how to handle these messages in your code.
When sending push notifications to your users, notification messages are the preferred method if you want to take advantage of the Firebase Console and let the Android system handle notification posting. Notification messages are high priority by default, and high priority FCM messages will still be delivered to users immediately even when the device is idle.
When using an FCM notification message, the system handles showing the notification on behalf of your app when it's in the background. When your app is in the foreground, the FCM notification message is delivered to the onMessageReceived()handler and you can handle it by posting a notification if needed or update the app content with the FCM payload data (Max 4KB) or fetch content from app server.
onMessageReceived()
An App server sends a notification message (or a notification message with a data payload) to a user:
getIntent()
Note: if the user dismisses the notification, data will not be delivered when app opens.
class SimpleFirebaseMessagingService : FirebaseMessagingService() { private val TAG = "spFirebaseMsgService" override fun onMessageReceived(remoteMessage: RemoteMessage) { // when App is in foreground, notification message: if (remoteMessage.notification != null) { // post notification if needed updateContent(remoteMessage.notification) } // process data payload } private fun updateContent(notification: RemoteMessage.Notification) {} }
SimpleFirebaseMessagingService.kt
You should use data messages if you need to handle the notification in the client app, whether to customize the notification or to decrypt the received payload data.
A data message is normal priority by default, which means it will be batched to the next maintenance window when the device is in Doze, by default.
When sending data messages, you need to handle the messages in the onMessageReceived() callback in the client app. The suggested approach in the handler is as following:
An App server sends data messages to notify users with end-to-end encrypted FCM message:
Note: Keep in mind that the FCM handler only has approximately 20 seconds once the message is received, as it's designed to complete short tasks like posting a notification. If you need to process longer than this window, we recommend scheduling a job or use the WorkManager API.
class SimpleFirebaseMessagingService : FirebaseMessagingService() { private val TAG = "spFirebaseMsgService" override fun onMessageReceived(remoteMessage: RemoteMessage) { // Use data payload to create a notification if (remoteMessage.data.isNotEmpty()) { // step 2.1: decrypt payload val notificationMessage = decryptPayload(remoteMessage.data) // step 2.1: display notification immediately sendNotification(notificationMessage) // step 2.2: update app content with payload data updateContent(remoteMessage.data) // Optional step 2.3: if needed, fetch data from app server /* if additional data is needed or payload is bigger than 4KB, App server can send a flag to notify client*/ if (remoteMessage.data["url"] != null) { scheduleJob() // use WorkManager when it's stable } } // process notification payload when app in foreground... } private fun decryptPayload(dataPayload: Map<String, String>): String { return "decrypted message" } private fun sendNotification(notificationMessage: String) {} private fun updateContent(dataPayload: Map<String, String>) {} private fun scheduleWork() { // it's recommended to use WorkManager when it's stable, use JobScheduler // on background work complete, update the notification if still active } }
Android has introduced many power improvement features in recent versions, so make sure you review and test your FCM use cases against these features. You can learn more about Android Power features and how it works with FCM from this blog post.
If you are not using FCM yet, it's time to upgrade. The C2DM library was officially deprecated in 2012 and shut down completely in 2015, making it no longer compatible with modern Android. We also announced in April 2018 that Google Cloud Messaging (GCM) server and client APIs have been deprecated and will be removed as soon as April 11th, 2019. You can find out more about the announcement and migration guides in this blog post.
To take advantage of all the new features and functionality that FCM and Android provide, we recommend using FCM today. To get started, visit the Firebase Cloud Messaging documentation.