Firebase Hosting with Environment Variables? - firebase

My Firebase application has dev & prod environments (two separate Firebase projects).
Issue: The config passed to firebase.initializeApp() is environment-dependent. Currently, I have this hardcoded. If I want to deploy to dev, I comment-out the initializeApp call with the prod config, and visa versa. Is there anyway to do this intelligently with environment variables? For instance, when I run the commands:
firebase use prod
firebase deploy --hosting
can 'prod' be passed as an environment variable to the javascript code so it knows to pass the prod-config to firebase.initializeApp()?

This is a fairly common development scenario and Angular has you covered. Beyond Firebase there are probably other options you may want to change depending on whether you are testing/deploying in development or production.
Check out the Angular docs for Building and serving Angular apps. This has all the info detailing the usage of this.
They make use of an environment.ts file, which most likely would include your Firebase development config, and an environment.prod.ts file, which would include your Firebase production config.
In your angular.json file you detail the configuration options where if you are building with a production option it would replace the environment.ts file with your envionrment.prod.ts file.
When using ng build it would use your dev config. When ready to test and deploy your app you would add a configuration switch, such as ng build --configuration=production

Related

Secure storage of credentials from auth.json when using CI

We use CircleCI to build our PHP app prior to deployment. One of the requirements in composer is a module stored in a private repository on Bitbucket.
Currently we store the credentials inside composer.json which is far from ideal.
The problem is that I can find no better solution for managing these credentials for repo access during the build. I'm assuming I can use an environment variable or similar.
The environment variable COMPOSER_AUTH is available to pass any number of authentication methods to composer and allows any keys or secrets to be managed outside of the repo.
In my example, to authenticate with bitbucket, the var looked like this:
export COMPOSER_AUTH='{"bitbucket-oauth": {"bitbucket.org": {"consumer-key": "xxxxxx","consumer-secret": "xxxxxx"}}}' (see: documentation)
CircleCi (and I'd assume most CI apps) has an environment variable settings page. Add the variable and value there and then you can remove the entire "bitbucket-oauth" block from composer.json.

Build Next.js app before deploying via Serverless Component

We're using the Next.js Serverless Component from: https://serverless-nextjs.com/ to deploy our Next.js app to AWS using the Serverless framework.
It takes around 7-8 mins for the app to be built and then deployed to AWS.
We were hoping to instead build the app up-front and then deploy the pre-built code...
You can tell Serverless to not build and just do the deployment with build.enabled: false:
# serverless.yml
myNextApplication:
component: "#sls-next/serverless-component#3.7.0"
inputs:
bucketName: our-bucket-name
build:
enabled: false
However when we run yarn next build the app is built under ./next.
When serverless builds the app it stores the state in .stateless and the files in .stateless_nextjs. So therefore the next build isn't compatible with deploying a prebuilt app...
This means if we try and build the app and then call serverless after we get the following error:
myNextApplication › Error: ENOENT: no such file or directory, open '/Users/cameron/Projects/nextjs-serverless/.serverless_nextjs/default-lambda/manifest.json'
So how do you build the app first and then deploy the build using Next.js Serverless Component?
Versions:
"dependencies": {
"next": "12.2.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"serverless": "2.72.2"
},
component: "#sls-next/serverless-component#3.7.0"
The reason is probably wrong next.js middleware setup. manifest.json is built upon simulated requests that goes through nextjs middlewares. please refer to this stackoverflow answer.
nextjs middleware had some structural changes around v12.x that requires migration. it's hard to figure out what's wrong because it gives little or no warning messages and it builds okay. I had similar issues too.
Solution
check if your deploy includes proper package lock file(yarn.lock, package-lock.json...) so that fixed version of next.js is included when deploying.
check latest middleware examples from github repo and try match middleware file structure and code.
check out nextjs middleware migration guide mentioned earlier; try build in local environment and make sure manifest.json is created.

Azure pipeline with multiple environments

My dotnetcore app has one appsettings.json per environment (appsettings.json and appsettings.Development.json for example) and I would like to take advantage of this on my pipeline.
I see 2 options for the pipeline:
Build Artifact for Dev -> Deploy on Dev -> Build Artifact for Prod -> Deploy on Prod
or
Build Artifact -> Deploy on Dev -> Deploy on Prod
For the first option, I could set the environment as a parameter for the build.
For the second option, how could I build the App only once, and set the environment according to the current deployment step? Taking advantage of the multiple appsettings.json I have.
And finally, are these approaches aligned with the best practices? If not, what would be the best practices for pipelines with multiple environments?
Generally we can generate a single artifact, then deploy the artifact to different environments and perform the different transformations at any environment within it's own stage release phase. That means we can change and override the settings which defined in the appsettings.json in each release environment.
Please refer to File transforms and variable substitution reference on how to do the transformation with .json files.
Besides, we can try to install the Replace Tokens extension, then use Replace Tokens task to load and change the settings defined in the appsettings.json file in each release environment/stage.
You can also transform the settings or use File Creator to create a new appsettings.jsonfile to overwrite the existing one.
Below blogs for your reference:
Replace appsetting tokens in config files with Build & Release
Management in VSTS (TFS)
Transform configurations in a .NET Core 2.2 Web API using Azure
DevOps
Using custom appsettings.json with ASP.NET Core integration
tests
You could go with Azure AppConfiguration and add it as an extra source for the configuration. This way your building/releasing process stays extremely simple.
See this documentation: https://learn.microsoft.com/en-us/azure/azure-app-configuration/enable-dynamic-configuration-dotnet-core
It's very powerful: you can select only part of the configuration (through filters), you can have feature flags, and you can have secrets (from linked key vaults).

Unable to change the default project to deploy my project on firebase hosting

i am trying to deploy my project on firebase hosting. And whenever i am using firebase init it is showing error in terminal as "firebaserc already has a default project " and it exit with that error
i have tried firebase logout and firebase login again . And used "firebase use" command also to change the project but it is still performing the firebase init action on the default project
i want to remove that default project
If you look very carefully at the messaging, it's saying that the name of the file is ".firebaserc" with a leading dot. This file indicates that firebase init was already run in this folder, and the contents of that file describe which project it's connected to (flairboat-48f7b). If you no longer want that file, delete it and start over. Since it starts with a dot, it might be hidden from normal view, but you can be sure that it exists.
you should write:
firebase use --add
and it work! You get the option to choose the preject from firebase.
I ran into the same issue.
Due to a small mistake in setting up the project in firebase, I had to delete it.
But later, I realized that my application NEEDS the default project to be hosted from firebase.
Since I found no shortcuts and running out of time, I did "this" to fix the issue in 10 minutes...with a 5-Step-Process. This is not a "Clever tip". But if you want things up and running soon, you can try this...
Create a new project (in my case, it's React project in VS Code IDE) using - npx create-react-app newprojectname to create a new react project with a different file name.(Don't delete or replace your previous project yet... )
While the new project is being created, create a new project in firebase to host your project.
Copy the folder from your old project that has all your work (it's "src" folder in case of React) and replace the "src" folder in the new project you created in your local machine.
Install all dependencies...Don't forget to add any dependencies you added to you old project. Look at the package.json file of the old project and import all dependencies.
Hit the start command (npm start in my case) and see your project running.
*I'll update if I found some firebase secret to resolve this issue. You can look for the same.
Ensure your firebase project support email and firebase initialize login email are same. If different? It won't be worked. so you must ensure it that two email (firebase project support email and firebase initialize email) are same.

How to setup different firebase environments in Flutter

I am trying to figure out how to set up different firebase environments in a flutter project.
I understand how to do this in firebase, I created two projects, one for production, one for the test. Then, in an iOS or Android project, I could use various methods to switch between these two environments using separate google-services.json or GoogleServices-Info.plist files.
In Flutter I found this description of how to separate environments, but it only explains how to differentiate between environments in the flutter code.
How can I get this environment to change what iOS and Android build at compile time? It would even be sufficient simply to allow a file copy hook at build time.
You can switch accounts using FirebaseApp.configure. You can offer your own solution or secret dev panel to switch between them.
The solutions will build flavours and plist implementations will lock you into builds when you deploy for TestFlight + they are messy.
Here's an example: (You could use Assets as well.)
// Load a named file.
let filePath = Bundle.main.path(forResource: "MyGoogleService", ofType: "plist")
guard let fileopts = FirebaseOptions(contentsOfFile: filePath!)
else { assert(false, "Couldn't load config file") }
FirebaseApp.configure(options: fileopts)
I wrote an article about how to do this for Firebase configuration as well as runtime configuration in dart code using flavors and platform channels.
https://medium.com/#matt.goodson.business/separating-build-environment-configurations-in-flutter-with-firebase-doing-it-the-right-way-c72c3ad3621f
Flutter flavors work pretty seamlessly with Android flavors. For iOS you need to create Xcode schemes for each flavor and link them to build configurations.
For dart configuration, you can use platform channels to get the flavor used during the build at runtime. This lets you configure the app without having multiple main.dart files or passing a target argument.
Salvatore Giordano has written a blog post with a detailed description of how to achieve this:
https://medium.com/#salvatoregiordanoo/flavoring-flutter-392aaa875f36
Flutter accepts a parameter --flavor=<flavor> which allows you to select different build flavors. In Android this works as expected, selecting different build flavors. IOS is a little tricker because a scheme is needed for every flavor, and the build configurations in the form of Release-<flavor> are also needed.
Once these parts are in place, they can be used, to select the firebase configuration as you would in any iOS or Android project.
The challenge is getting Dart code to also be aware of the flavor, and the blog post provides no good solution for this. It suggests the standard method of using different entry points can be used, but the correct entry point must be matched to the correct flavor manually by the person invoking the app.
Specifically to Firebase env config you can use this article and this article from CodeMagic which explains how you can set up plist files with build env variables.
If you need to have a different set of values inside your Dart code, like an option you can use this package. It allows to generate Dart class config file from console command params.
Update 12/05/2020
Since Flutter 1.17 you can actually use compile-time variables with --dart-define argument in flutter run and flutter build commands
Here is an article that describes how to specify and use them.
With the release of Flutter for Web to the stable channel, I put together instructions for targeting multiple firebase projects (e.g. dev, staging, prod) from multiple build platforms (i.e. iOS, Android, and Web).

Resources