The Firebase console gives you the power to make changes to your Cloud Firestore Security Rules directly from your browser! Unfortunately, that also means your team has the ability to break your security rules directly from your browser, maybe without remembering exactly what they changed. Well fear no more; Firebase has your back!
Recently, we added Version History to Cloud Firestore Security Rules. For any Cloud Firestore project, you can now browse all previously published versions of Rules, view the differences between the previous and current versions, and edit the current version -- either to a complete rollback to an earlier version or to a mix of rules.
Now, when your team introduces a bad security rule, it's a snap to find out what the previous working version was and get back to it.
To start using version history for Security Rules, simply navigate to the Rules tab of Cloud Firestore, and start browsing your version history in the left-hand column. From any older version, you can click "Compare to Latest" to view the diff and edit the latest version.
Every deploy that includes Rules is considered a new version; you'll see unchanged versions if you've deployed unchanged rules several times from the command line. To avoid that, you can call deploy --only from the Firebase CLI to deploy only the things you've changed. For example, I often make edits to my project's Cloud Functions without changing anything else, so I end up running firebase deploy --only functions from the command-line tool to make sure only the changes to my Cloud Functions get submitted.
deploy --only
firebase deploy --only functions
Reach out to us via Twitter @Firebase or via our other support channels to let us know what you think! We're looking forward to adding this to other Firebase features, and would like to get your feedback before we do.
Last year, we launched the beta of Cloud Functions for Firebase to help you build backend functionality for your app without worrying about managing servers. It lets you write in JavaScript or Typescript, deploy to Google's Cloud infrastructure, and execute in response to app events. Today we're pleased to release version 1.0 of the Cloud Functions for Firebase SDK - along with new, frequently requested improvements for the development, testing and monitoring of Functions.
The Firebase SDK for Google Cloud Functions enables you to extend other Firebase products, giving users the features they need in your apps. One of our earliest customers, Posse, makers of the Hamilton app, needed to create a lottery system to give fans a chance to win tickets to the massively popular Broadway play - without the overhead of managing their own servers. When a user enters the lottery, Functions powered logic runs in the cloud with results stored directly to Cloud Firestore. Lottery results are pushed automatically to lucky fans' Hamilton mobile app.
Posse also needed to scale the Hamilton app. When the lottery opens, the app's usage can suddenly surge multifold before normalizing a few minutes later. Functions automatically scales without needing any action from Posse, and their client only pays for the resources they use.
In addition to ticket lotteries, Posse also used Functions to integrate with other Firebase products to:
There's a great deal of things you can do with Functions. For more use cases and sample code, see our popular GitHub repo.
Today's v1.0 release comes with a number of new features based on your feedback - here's the lowdown!
One of your biggest requests was for an easy way to directly call Functions from your client apps. To facilitate that, we're adding a new type of function, along with SDKs for iOS, Android, and web clients. The new type is a Callable HTTPS function that manages an HTTPS request from the client SDK. Callable HTTPS functions drastically reduce the amount of boilerplate code you have to write to make HTTPS requests to Functions.
Here's how it works:
For more, check out our docs!
While Functions Shell gave you the ability to interact with your functions locally, it was not optimal for writing unit tests such as those that run in a CI system. That's why we are launching a new firebase-functions-test npm module that simplifies writing unit tests. firebase-functions-test takes care of the necessary setup and teardown, allowing easy mocking of test data. Now, you can either write completely offline tests that have no side effects, or tests that interact with a development Firebase project - where you can observe the success of actions such as database writes.
Last fall, we introduced the ability to emulate your functions locally via the Firebase CLI through both the "firebase serve --only functions" and "firebase experimental:functions:shell" command. These were experimental features, and now we are officially supporting them. "firebase experimental:functions:shell" has been renamed to "firebase functions:shell", and "firebase serve" will emulate all HTTPS functions by default without the need for the "--only" flag.
After deploying functions, you may be wondering: "What's happening with my functions? How is my app performing? Is anything broken?" With today's release, you can now keep tabs on any errors in your functions via the new health monitor:
Additionally, you can track your functions' performance, latency and memory usage:
The APIs for writing Cloud Functions with the Firebase SDK have changed in this v1.0 SDK release. This means that upgrading to the new SDK will require some updates to any code you've already written during the beta. But don't worry - this doesn't affect any functions you have already deployed. To see what has changed and how to adapt to the new format, just follow our migration guide!
If you're just getting started with the Firebase SDKs for Cloud Functions, try following our step-by-step Codelab and visiting the documentation. There is also a video tutorial to help get you set up using TypeScript as the recommended programming language.
We hope you find these new features helpful. While the Firebase SDKs for Cloud Functions are fully released, the Cloud Functions platform is still in beta. Stay tuned for more updates!
We launched the Google URL Shortener back in 2009 as a way to help people more easily share links and measure traffic online. Since then, many popular URL shortening services have emerged and the ways people find content on the Internet have also changed dramatically, from primarily desktop webpages to apps, mobile devices, home assistants, and more.
To refocus our efforts, we're turning down support for goo.gl over the coming weeks and replacing it with Firebase Dynamic Links (FDL). FDLs are smart URLs that allow you to send existing and potential users to any location within an iOS, Android or web app. We're excited to grow and improve the product going forward. While most features of goo.gl will eventually sunset, all existing links will continue to redirect to the intended destination.
Starting April 13, 2018, anonymous users and users who have never created short links before today will not be able to create new short links via the goo.gl console. If you are looking to create new short links, we recommend you use Firebase Dynamic Links or check out popular services like Bitly and Ow.ly as an alternative.
If you have existing goo.gl short links, you can continue to use all features of goo.gl console for a period of one year, until March 30, 2019, when we will discontinue the console. You can manage all your short links and their analytics through the goo.gl console during this period.
After March 30, 2019, all links will continue to redirect to the intended destination. Your existing short links will not be migrated to the Firebase console, however, you will be able to export your link information from the goo.gl console.
Starting May 30, 2018, only projects that have accessed URL Shortener APIs before today can create short links. To create new short links, we recommend FDL APIs. FDL short links will automatically detect the user's platform and send the user to either the web or your app, as appropriate.
If you are already calling URL Shortener APIs to manage goo.gl short links, you can continue to use them for a period of one year, until March 30, 2019, when we will discontinue the APIs.
As it is for consumers, all links will continue to redirect to the intended destination after March 30, 2019. However, existing short links will not be migrated to the Firebase console/API.
URL Shortener has been a great tool that we're proud to have built. As we look towards the future, we're excited about the possibilities of Firebase Dynamic Links, particularly when it comes to dynamic platform detection and links that survive the app installation process. We hope you are too!
All too often I become frustrated when building an authentication component. The asynchronous flow is hard to manage and it makes my template a mess of ngIfs and Elvis operators:
{{ (user | async)?.uid }}
The problem is always same. I'm mixing too many concerns in one place. Organizing the right code in the right place is what makes a happy codebase.
The solution: Store route specific code in Angular's Route Guards.
The AngularFireAuth service is a great match for routing code. It contains information about a current user, whether they are coming from a redirect, and all sorts of other things.
AngularFireAuth
Take a simple signInWithRedirect example:
signInWithRedirect
import { Component, OnInit } from '@angular/core'; import { AngularFireAuth } from 'angularfire2/auth'; import { Router } from '@angular/router'; import * as firebase from 'firebase/app'; @Component({ selector: 'app-login', template: ` <button class="btn" (click)="auth()"> Login </button> `, styleUrls: ['./login.scss'] }) export class LoginComponent implements OnInit { constructor( private afAuth: AngularFireAuth, private router: Router ) { } ngOnInit() { this.afAuth.getRedirectResult().then(result => { if(result) { this.router.navigateByUrl('profile'); } }); } auth() { const provider = new firebase.auth.GoogleAuthProvider(); this.afAuth.auth.signInWithRedirect(provider); } }
Here's what's going in this example:
auth()
signInWithRedirect()
getRedirectResult()
ngOnInit()
navigateByUrl()
This isn't a problem with one component. However, imagine having to manage redirects in multiple components.
The code in ngOnInit belongs in a Route Guard. This will clean up the component of routing logic and remove the Router dependency entirely.
ngOnInit
Router
A Route Guard is used for all sorts of useful things. In this case a guard can handle the redirect code.
@Injectable() export class RedirectGuard implements CanActivate { constructor( private authService: AngularFireAuth, private router: Router ) {} canActivate() { this.authService.auth.getRedirectResult().then(result => { if(result.user != null) { this.router.navigateByUrl('profile'); return false; } return true; }); } }
The canActivate method determined if the user has access to the route. Here's what happens:
canActivate
'profile'
This code is now reusable. The Angular Router lets you specify which routes you want to listen for a redirect.
import { Routes, RouterModule } from '@angular/router'; import { LoginComponent } from './login/login.component'; import { RedirectGuard } from './redirect.guard'; const ROUTES: Routes = [ { path: '', component: LoginComponent, canActivate: [RedirectGuard] }, { path: 'profile', loadChildren: 'app/profile/profile.module#ProfileModule' } ]; const AppRoutes = RouterModule.forRoot(ROUTES); export { AppRoutes }
Now the LoginComponent is free of routing code:
LoginComponent
@Component({ selector: 'app-login', template: ` <button class="btn" (click)="auth()"> Login </button> `, styleUrls: ['./login.scss'] }) export class LoginComponent { constructor(private afAuth: AngularFireAuth) { } auth() { const provider = new firebase.auth.GoogleAuthProvider(); this.afAuth.auth.signInWithRedirect(provider); } }
No more async flow mess. The right code is organized in the right place. You can add the RedirectGuard to more routes as the app grows, which keeps the complexity out of your components.
RedirectGuard
Dashboards are great, but what if you're not checking them? Wouldn't it be great to know when you have a huge spike in traffic, or if you're about to hit your concurrent connections limit for a single database? Don't worry, Google Stackdriver Alerts have you covered!
Back in December, we announced that the Firebase Realtime Database has integrated with Google Stackdriver to let you create dashboards and graphs of powerful new metrics. We also have more in-depth descriptions of these metrics available in our documentation, as well as other monitoring and debugging tips for your databases. Now we've made all this data actionable through Google Stackdriver Alerts!
You can set alerts that will trigger actions whenever particular conditions are met. For example, if the metric io/database_load goes over 90% for more than one minute, an email will go out to your engineering team. It's also possible to include documentation in your alert, which can help if you haven't yet had your morning coffee. To learn more about conditions that can trigger alerts, see the Condition details documentation.
io/database_load
In addition to the plethora of available conditions, Google Stackdriver also lets you choose how to be alerted. On the basic tier, you can be notified via email or the Google Cloud Console Mobile App. On the premium tier, you're able to create an incident via PagerDuty or have a message posted to your Slack Channel. One of my personal favorite premium notifications is the Webhook option, which you can even use to trigger a Cloud Function to help you diagnose the issue. For the load example, when your database is nearing 100% load, you could start a Cloud Function, have it profile your database, then report the findings to your Slack Channel.
Setting up a custom alert in Stackdriver is a straightforward process. Start by heading over to the Stackdriver Monitoring Console. Once you've signed up for an account, navigate to Alerting > Create a Policy. You should see a panel like this:
For this alerting policy, I've specified that when my database utilization is over 90% for more than a minute, I'll receive an email at alerts@you.com with the name of the policy, plus the documentation I specified. Now all I need to do is hit the Save Policy button, and my alert is live!