The firebase Web-App guide states i should put the given apiKey in my Html to initialize firebase:

// TODO: Replace with your project's customized code snippet
<script src="https://www.gstatic.com/firebasejs/3.0.2/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: '<your-api-key>',
    authDomain: '<your-auth-domain>',
    databaseURL: '<your-database-url>',
    storageBucket: '<your-storage-bucket>'
  };
  firebase.initializeApp(config);
</script>

By doing so the apiKey is exposed to every visitor. What is the purpose of that key and is it really meant to be public?

4 Answers 11

up vote 122 down vote accepted

The apiKey essentially just identifies your Firebase project on the Google servers. It is not a security risk for someone to know it. In fact, it is necessary for them to know it, in order for them to interact with your Firebase project.

In that sense it is very similar to the database URL that Firebase has historically been used to identify the back-end: https://<app-id>.firebaseio.com. See this question on why this is not a security risk: How to restrict Firebase data modification?, including the use of Firebase's server side security rules to ensure only authorized users can access the backend services.

2 upvote
  flag
So it means that other people would be able to access all the data in my firebase database? – Emmanuel Campos
upvote
  flag
7 upvote
  flag
@EmmanuelCampos Answer is Yes and No. Yes, if you allow or want the other people to access all the data in the database. And No, if you don't want them to. Firebase database has rules, rules that you control – Rexford
upvote
  flag
@Rexford How about user management? Wouldn't they just create a new app then they would use the auth of my app and they would be able to register their users in my users table? – Emmanuel Campos
2 upvote
  flag
Found my answer here for my last question support.google.com/firebase/answer/6400741 Thanks for the help. This link may help someone in the future. – Emmanuel Campos
upvote
  flag
How does it prevent on some user create a app based on my inicialization code? – m.rufca
3 upvote
  flag
@m.rufca , your data should be available for users, who are authenticated. And here is the trick. By default, in your firebase settings only localhost and your project domains are authorized to perform authentication from them. So nobody else can create app which will normally work with your firebase. – Artem Arkhipov
upvote
  flag
@Tamango This is good because prevent from user publish an app using my firebase service. But what if he runs on localhost? I'm asking this because I want to but my app code on github. – m.rufca
upvote
  flag
@m.rufca , I tried to find something about that and found logical answer from one of the firebase developers (posted on 16 december 2016): "It is not possible to disable localhost, but being able to run your code locally gives them no more permissions than running it from your production site. The user will only have access to their own /users/$uid node and will not be able to access any other user's data. There is no security issue here." Of course you are expected to configure firebase security rules before to allow users read/write only to their own parts of database. – Artem Arkhipov
6 upvote
  flag
what if bot is creating unlimited users at my app. How can I require captcha. – Muhammad Umer

Building on the answers of prufrofro and Frank van Puffelen here, I put together this solution that doesn't prevent scraping, but can make it harder to use your API key.

Warning: To get your data, even with this method, one can for example simply open the JS console in Chrome and type:

firebase.database().ref("/get/all/the/data").once("value", function (data) {
    console.log(data.val());
});

Only the database security rules can protect your data.

Nevertheless, I restricted my production API key use to my domain name like this:

  1. https://console.developers.google.com/apis
  2. Select your Firebase project
  3. Credentials
  4. Under API keys, pick your Browser key. It should look like this: "Browser key (auto created by Google Service)"
  5. In "Accept requests from these HTTP referrers (web sites)", add the URL of your app (exemple: projectname.firebaseapp.com/* )

Now the app will only work on this domain name. So I created another API Key that will be private for localhost developement.

  1. Click Create credentials > API Key

This one is not restricted, so make sure you keep it private.

I use Webpack to build my production app. In order to make sure I don't publish this new unrestricted API key by mistake, I put it inside my index.html just as you would normally do with your API key. Then, inside my webpack.production.config.js file, I replace the key every time index.html is copied to the production build, like this:

plugins: [
    new CopyWebpackPlugin([
      {
        transform: function(content, path) {
          return content.toString().replace("###dev-key###", "###public-key###");
        },
        from: './index.html'
      }
    ])
  ]

By default, as mentioned by Emmanuel Campos, Firebase only whitelists localhost and your Firebase hosting domain.

upvote
  flag
Is that working fine for you? Was thinking to do the same thing for an Android app. I wonder why Firebase doesn't cover that in the security section. – MScott
1 upvote
  flag
I've had no problem so far, but probably no attacks either – z0me
2 upvote
  flag
This is not mentioned in their guide because it won't protect you from scraping. All this ensures is someone else can not make a web app that uses your firebase to read (or write) data, if it's run in a normal well behaved browser. – thoutbeckers
upvote
  flag
@thoutbeckers you're right, thank you. I edited the answer, but left the method as it might still be useful. – z0me

I am not convinced to expose security/config keys to client. I would not call it secure, not because some one can steal all private information from first day, because someone can make excessive request, and drain your quota and make you owe to Google a lot of money.

You need to think about many concepts from restricting people not to access where they are not supposed to be, DOS attacks etc.

I would more prefer the client first will hit to your web server, there you put what ever first hand firewall, captcha , cloudflare, custom security in between the client and server, or between server and firebase and you are good to go. At least you can first stop suspect activity before it reaches to firebase. You will have much more flexibility.

I only see one good usage scenario for using client based config for internal usages. For example, you have internal domain, and you are pretty sure outsiders cannot access there, so you can setup environment like browser -> firebase type.

You can use firebase remote config by which it will be secure.

Not the answer you're looking for? Browse other questions tagged or ask your own question.