Cloud function storage and deploy target - firebase

I'm using deploy targets on Firebase and everything is working fine except my Cloud functions.
The process.env.FIREBASE_CONFIG env variable doesn't have the right values. The properties "databaseURL" and "storageBucket" are not the one I've configured the target to use
When I use admin.database() it doesn't use the right RTDB I've created and that I want to use
functions.storage.object().onFinalize() doesn't "watch" the right bucket
My .firebaserc file
{
"projects": {
"default": "hatch-rpg",
"dev": "hatch-rpg"
},
"targets": {
"hatch-rpg": {
"hosting": {
"shadra": [
"shadra"
]
},
"database": {
"shadra": [
"hatch-shadra-dev"
]
},
"storage": {
"shadra": [
"hatch-shadra-dev"
]
}
}
}
}
My firebase.json file
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"database": [
{ "target": "shadra", "rules": "database.rules.json" }
],
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
],
"source": "functions"
},
"hosting": [
{
"target": "shadra",
"public": "dist/shadra",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
],
"storage": [
{ "target": "shadra", "rules": "storage.rules" }
]
}
I'm initializing Firebase like this
admin.initializeApp(functions.config().firebase);
What am I missing ?
Thanks a lot
EDIT:
I have tried to override FIREBASE_CONFIG by doing firebase functions:config:set firebase.databaseURL="hatch-shadra-dev.firebaseio.com" firebase.storageBucket="hatch-shadra-dev" but it didn't worked because Invalid config name firebase.databaseURL, cannot use upper case. then tried without uppercase and got Cannot set to reserved namespace firebase
How can I override this FIREBASE_CONFIG ? or should I just not use it initialize manually firebase ?

Ok, here's what I did to fix this issue.
Maybe there's a better option or I'm just mis-using Firebase here.
Anyway, heres' the solution:
First, add some config to the project
firebase functions:config:set target.database="hatch-shadra-dev.firebaseio.com" target.bucket="hatch-shadra-dev"
Then use it in the Cloud function with admin.initializeApp()
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
const config = functions.config();
admin.initializeApp({
...config.firebase,
storageBucket: config.target.bucket,
databaseURL: `https://${config.target.database}`
});

Related

React Native Firebase Emulator - Can't connect to firestore emulator

I'm currently trying to setup a locally environment with react native expo and React Native Firebase (using EAS to build). I've successfully connected the app with the authentication emulator receiving a verification code through phone authentication. However, I am not able to connect to the firestore emulator. The error I get when I try to fetch documents is the following
[Error: [firestore/unavailable] The service is currently unavailable. This is a most likely a transient condition and may be corrected by retrying with a backoff.]
I hope some of you guys can help me with a solution. Currently my code looks like this in index.js:
//index.js file
import Constants from "expo-constants";
import "#react-native-firebase/app";
import firestore from "#react-native-firebase/firestore";
import auth from "#react-native-firebase/auth";
if (__DEV__) {
const origin =
Constants.manifest?.debuggerHost?.split(":").shift() || "localhost";
firestore().useEmulator(origin, 8080);
auth().useEmulator("http://localhost:9099");
}
...
My firebase.json file looks like this:
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"storage": {
"rules": "storage.rules"
},
"functions": [
{
"source": "functions",
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
],
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}
],
"emulators": {
"auth": {
"port": 9099
},
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"pubsub": {
"port": 8085
},
"storage": {
"port": 9199
},
"ui": {
"enabled": true
},
"singleProjectMode": true
}
}

"Ref does not have a version" error when trying to install an extension locally using Firebase CLI

I installed stripe/firestore-stripe-payments extension using Firebase Console (https://firebase.google.com/products/extensions/stripe-firestore-stripe-payments) and it works fine.
However, I wanted to install the extension locally so I can have a full testing environment using Firebase Local Emulator Suite.
The issue is that whenever I try to run firebase ext:install stripe/firestore-stripe-payments using both firebase-tools 11.8.1 and 11.14.1, it shows the following error:
I tried looking online but it seems that this error is not common.
Here's my firebase.json:
{
"database": {
"rules": "database.rules.json"
},
"functions": {
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
],
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
],
"source": "functions"
},
"emulators": {
"auth": {
"port": 9099
},
"functions": {
"port": 5001
},
"database": {
"port": 9000
},
"ui": {
"enabled": true
},
"firestore": {
"port": 8080
},
"storage": {
"port": 9199
},
"hosting": {
"port": 5000
},
"pubsub": {
"port": 8085
},
"eventarc": {
"port": 9299
}
},
"remoteconfig": {
"template": "remoteconfig.template.json"
},
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"storage": {
"rules": "storage.rules"
},
"hosting": {
"public": "./web/build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
Thank you in advance
The v11 version of firebase-tools works quite differently to previous major versions.
To run locally, you will need to make a few additions.
1). Add an extensions object to your firebase.json and use a relative path to point to the route of the stripe extension (basically where the extension.yaml lives).
"extensions": {
firestore-stripe-payments: "../path-to-extension-yaml"
}
2). Next you will require a new folder to host your extension configuration.
Add a new folder called "extensions" in the same directory as your firebase.json.
Create new files for local config (this must match the extension you are attempting to emulate).
For example:
firestore-stripe-payments.env.local for main configuration
firestore-stripe-payments.secret.local for secrets
LOCATION=us-central-1
PRODUCTS_COLLECTION =products
etc...
3). Finally, run firebase emulators:start -P ${project_id}, it is recommended to use the prefix demo-, as in demo-project` to avoid emulating any production services.
For more guidelines with Stripe, the official repository has an example or extensions tests https://github.com/stripe/stripe-firebase-extensions/tree/next/firestore-stripe-payments/_emulator
I fixed the error by specifying the exact version, according to this GitHub comment.
The latest version can be found as version in extension.yaml in the official repository, which "source code" link in Firebase's extension page can refer to it, in my case:
https://github.com/stripe/stripe-firebase-extensions/blob/master/firestore-stripe-payments/extension.yaml
So, I used this command and it worked!
firebase ext:install stripe/firestore-stripe-payments#0.3.1
It took care of the firebase.json and extensions/firestore-stripe-payments.env automatically.
If you already installed the extension via console.firebase.google.com, use the following command to import the configuration:
firebase ext:export --project=XXXX
Then, override any attribute in extensions/firestore-stripe-payments.env.local as #darren-ackers mentioned.
There's a pending PR that covers most of these steps in addition to webhook configuration, here's the relevant file (README):
https://github.com/stripe/stripe-firebase-extensions/pull/436/files

Firebase Hosting deploys CRA app to 'build' subdirectory

What is happening
When I execute firebase deploy --only hosting given the below folder structure, it deploys the entirety of the ui folder. Meaning, I will have to visit my app at http://my-app.web.app/build.
What I would like to happen
I want to deploy the contents of the build folder generated in the predeploy step of firebase.json as the root of the application. So that my-app/ui/build/index.html ultimately winds up as http://my-app.web.app.
What else have I tried
I thought it would work if I specified "public": "ui/build" in firebase.json, but what happens then is the following error about ui/build/package.json not being found.
npm ERR! enoent ENOENT: no such file or directory, open 'C:\Users\me\Projects\my-app\ui\build\package.json'
I understand it's looking for ui/build/package.json because of public: ui/build but how can I tell it to build from the ui folder, but deploy the resulting build folder?
folder structure
my-app
functions/
ui/
build (after npm run build, at least)
src/
whatever.tsx
.firebaserc
firebase.json
firestore.indexes.json
firestore.rules
firebase.json
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run build"
],
"source": "functions"
},
"hosting": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run build"
],
// this is the problem line
"public": "ui",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
"emulators": {
"auth": {
"port": 9099
},
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"hosting": {
"port": 5000
},
"ui": {
"enabled": true
}
}
}
Oof! Couldn't see it through the trees.
I simply divorced the predeploy script from the public setting in firebase.json:
Set the pre-deploy to target the ui folder ( because $RESOURCE_DIR will become ui/build) and set the public value to ui/build:
"hosting": {
"predeploy": [
"npm --prefix ui run build"
],
"public": "ui/build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},

Firebase deployed to wrong hosting when multiple projects used

I have two firebase projects: myapp for prod, and myapp-dev for dev environment.
I first used the firebase cli to init my project with "myapp" and so all the files were generated with this, including the hosting resource myapp (so I can deploy my app to myapp.web.app).
Then I have added a second firebase project ("myapp-dev"). I run those
firebase use --add myapp-dev # I have selected the right myapp-dev firebase project and set `dev` as short name
firebase target:apply hosting myapp-dev myapp # note here that I also use name "myapp" as resource
I have manually changed my .firebasesrc because I want the dev project to be default...
So my .firebasesrc looks like this
{
"projects": {
"default": "myapp-dev",
"prod": "myapp"
},
"targets": {
"myapp": {
"hosting": {
"myapp": [
"myapp"
]
}
},
"myapp-dev": {
"hosting": {
"myapp": [
"myapp"
]
}
}
}
}
and firebase.json
{
"hosting": [
{
"target": "myapp",
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
],
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
]
}
}
Now when I ran those lines, the webapp got deployed to the prod env, the functions to the dev env...
firebase use myapp-dev
firebase deploy
EDIT
Running firebase target:apply hosting myapp myapp-dev helped !
In my case I had the same app deploying to 2 different environments (development and production). The documentation is not very clear on this scenario, took some playing around to get the right config.
.firebaserc
{
"projects": {
"production": "myapp-prod",
"development": "myapp-dev"
},
"targets": {
"myapp-prod": {
"hosting": {
"myapp": [
"site-name-prod"
]
}
},
"myapp-dev": {
"hosting": {
"myapp": [
"site-name-dev"
]
}
}
}
}
firebase.json
{
"hosting": [{
"target": "myapp",
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
}]
}
To deploy to production run
firebase use production
firebase deploy
To deploy to development
firebase use development
firebase deploy
When you run firebase deploy in the project, it uses the target specified in the hosting section on the firebase.json to deploy to the site name specified in the hosting section of the target in the .firebaserc
I think your config should be something like this.
file .firebasesrc
"targets": {
"myapp-dev": {
"hosting": {
"myapp-dev": [
"myapp-dev"
],
"myapp": [
"myapp"
]
}
}
}
file firebase.json:
"hosting": [
{
"target": "myapp-dev",
"public": "build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
{
"target": "myapp",
"public": "dist/myapp", /* folder */
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
]
and then deploy using target documentation

How to set multiple environments for Firebase

For my project I use staging and production environment.
fileReplacements property inside angular.json is used to change files:
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
},
{
"replace": "src/app.html",
"with": "src/app.prod.html"
}
]
to change between environments .firebaserc files is used.
Now I need to use different firebase config files per environment ( firebase.json and firebase.prod.json )
Is it possible to do it? I thought to use predeploy scrips, but don't know how
I have done it using single .firebaserc file. You can add different targets to deploy.
firebase target:apply type target-name resource-name
ref: [ https://firebase.google.com/docs/cli/targets && https://firebase.google.com/docs/cli/ ]
// firebase.json
"hosting": [
{
"target": "prod",
"public": "dist/<folder_name>,
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
]
// .firebaserc file
// Sample: here the "projects" are your targets
{
"projects": {
"default": "staging-project",
"dev": "staging-project",
"prod": "prod-project"
},
"targets": {
"staging-project": {
"hosting": {
"stage": [
"staging-project"
],
"admin-stage": [
"your-admin-stage"
],
"admin-prod": [
"your-admin-prod"
],
"prod": [
"prod-project"
]
}
}
}
}
// in the build script
firebase use dev
firebase deploy --only firestore:rules,hosting:stage,functions...

Resources