firebase-functions: 1.0.0
firebase-tools: firebase/firebase-tools.git#ll-fixfbconfig2 (3.18.1) See firebase/firebase-tools/issues/722
firebase-admin: 5.11.0
See steps to reproduce. Related to firebase/firebase-functions/issues/216.
firebase init functions (Choose TypeScript and TSLint during setup)cd functions"express": "^4.16.3", in package.jsonrm -rf node_modules then npm installindex.ts withimport * as admin from 'firebase-admin';
admin.initializeApp();
exports['debug'] = require(`${__dirname}/debug.js`);
debug.ts withimport * as express from 'express';
import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';
const app = express();
app.get('/', async (request, response) => {
try {
await admin.database().ref().once('value') as admin.database.DataSnapshot;
} catch (error) {
console.error(error);
return response.status(500).send(error);
}
return response.status(200).send('OK');
});
export = functions.https.onRequest((request, response) => {
// https://github.com/firebase/firebase-functions/issues/27#issuecomment-292768599
if (!request.path) {
request.url = `/${request.url}`;
}
return app(request, response);
});
npm run deployhttps://us-central1-project-id.cloudfunctions.net/debug
Yes.
Status Code: 200
Body: OK
Status Code: 500
Body: {"code":"database/invalid-argument","message":"Can't determine Firebase Database URL."}
{ Error: Can't determine Firebase Database URL.
at FirebaseDatabaseError.Error (native)
at FirebaseDatabaseError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:39:28)
at new FirebaseDatabaseError (/user_code/node_modules/firebase-admin/lib/utils/error.js:190:23)
at DatabaseService.ensureUrl (/user_code/node_modules/firebase-admin/lib/database/database.js:75:15)
at DatabaseService.getDatabase (/user_code/node_modules/firebase-admin/lib/database/database.js:52:26)
at FirebaseApp.database (/user_code/node_modules/firebase-admin/lib/firebase-app.js:235:24)
at FirebaseNamespace.fn (/user_code/node_modules/firebase-admin/lib/firebase-namespace.js:283:45)
at Object.<anonymous> (/user_code/lib/debug.js:16:21)
at next (native)
at /user_code/lib/debug.js:7:71
errorInfo:
{ code: 'database/invalid-argument',
message: 'Can\'t determine Firebase Database URL.' } }
@laurenzlong Unfortunately I'm seeing this again with some of my functions, but not all.
I've tried "firebase-tools": "https://github.com/firebase/firebase-tools.git#ll-fixfbconfig2" and still getting the same as @zgosalvez in a functions.database function.
I'm going to go back to the try catch initializeApp() in each function workaround I mentioned in https://github.com/firebase/firebase-functions/issues/216
@ahaverty, with the above snippets. How would you implement the workaround?
Remove the admin.initializeApp(); from index.ts
And add this under your imports in debug.ts
try {
admin.initializeApp();
} catch(error) {
//TODO: ignoring until firebase-functions fix released
}
I've yet to hit issues with that, I'll update here if I do.
_If that doesn't fix it for you, it sounds like it's actually some weird timing/race issue and only working for me because of the time it takes to export all my functions. 馃
_Plan C if that doesn't work for you, is to add a tempFirebase to my firebase function configuration, which seems to be guaranteed to be gettable from index.ts_ (Let me know if it doesn't work for you, i'll join you in Plan C just to be safe 馃槃)
@ahaverty, that didn't work either; Same erroneous behavior.
@zgosalvez Damn. Thoughts on using a temporary custom firebase config?
I want to hold off a more complicated workaround until we get feedback from @laurenzlong (or anyone from the Firebase team). This may be a simple fix on their end and I'm going to sleep soon. Thank goodness it's still the weekday in SFO. I'll hang ten for now. Feel free to do _Plan C_ in the meantime. 馃
Deploying tonight (It's Friday in Ireland), I think I'll go with Plan C for now 馃
_I'll post up how it goes_
Good night 馃憢 馃寜
According to @inlined (https://twitter.com/inlined/status/982277528751489025) we need to import firebase-functions before calling initializeApp()
Which I believe explains why some functions were working and others weren't.
Ok, that didn't work either. console.log(process.env.FIREBASE_CONFIG) gives me undefined even after importing firebase-functions beforehand.
I also tried doing what firebase are doing, inside my functions:
import { AppOptions, initializeApp } from 'firebase-admin';
let firebaseConfig = JSON.stringify({
databaseURL: `https://${process.env.GCLOUD_PROJECT}.firebaseio.com`,
storageBucket: `${process.env.GCLOUD_PROJECT}.appspot.com`,
projectId: process.env.GCLOUD_PROJECT,
});
initializeApp(firebaseConfig as AppOptions);
but I got this on deploy attempt:
Error: Error occurred while parsing your function triggers.
Error: Invalid Firebase app options passed as the first argument to initializeApp() for the app named "[DEFAULT]". Options must be a non-null object.
at FirebaseAppError.Error (native)
at FirebaseAppError.FirebaseError [as constructor] ...
TL;DR: Though it's a bit hacky, can you try requiring firebase-functions before calling admin.initializeApp()?
(background)
We are in the process of providing a server-side contract for Cloud Functions that lets you auto-initialize the Firebase Admin SDK, but that still hasn't completed unfortunately.
Until then, requiring firebase-functions will silently ensure the new model (the FIREBASE_CONFIG env var) on any environment deployed with the firebase CLI.
@inlined I've tried import * as functions from 'firebase-functions' but it's still giving me the above + console.log(process.env.FIREBASE_CONFIG) is undefined.
Or do you mean call it as a _require_ like: require('firebase-functions')?
I just got the following working in my index.ts, although it looks like firebase-functions is favouring some internal firebase config call and if else'ing to this:
import { AppOptions, initializeApp } from 'firebase-admin';
initializeApp({
databaseURL: `https://${process.env.GCLOUD_PROJECT}.firebaseio.com`,
storageBucket: `${process.env.GCLOUD_PROJECT}.appspot.com`,
projectId: process.env.GCLOUD_PROJECT,
});
Would you recommend sticking with this or going with the require('firebase-functions')? 馃
Thanks for the help
Module loading in TypeScript has a few really subtle nuances to it; I think you've triggered lazy loading with the as statement. In TypeScript, you import a module for side effects with
import 'firebase-functions';
(a require statement would also work, though in some typescript configs you'll have to declare the existence of the require function first).
If the GCLOUD_PROJECT trick works for you, then that's fine as long as the code is not open source. There exist a small percentage of projects in the world where that code won't work. The databaseURL or storageBucket may not be the GCLOUD_PROJECT if the project is old enough.
@inlined, I changed the index.ts snippet to this and it worked (even on my actual project)! 馃憦馃徏
// https://github.com/firebase/firebase-functions/issues/220#issuecomment-379312738
// tslint:disable-next-line:no-import-side-effect
import 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
exports['debug'] = require(`${__dirname}/debug.js`);
It kind of makes sense now since I removed import * as functions from 'firebase-functions; when I migrated to v1. I noticed I wasn't using functions in index.ts so I removed it. I'll retain it until your server-side contract is complete. Importing in TypeScript is such a nuisance; I still can't get my head around it.
For now, I'll monitor the health of my functions in the coming days. Thanks for the new health dashboard in the Firebase console, and of course thank you for the insight into this issue. 馃帀
We are in the process of providing a server-side contract for Cloud Functions that lets you auto-initialize the Firebase Admin SDK, but that still hasn't completed unfortunately.
@inlined Why isn't this documented anywhere in the docs (at least doesn't seem like it)?
This was supposed to go away sooner. We're looking into ways to remove the subtlety rather than hiding it in docs. If we can't do this soon, then a doc note is certainly appropriate.
I'm in the same situation except I'm using javascript. My first three lines are:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
And I'm also getting the "Can't determine Firebase Database URL" error when a firebase function is called. Specifically, when admin.database() is called.
version 3.18.4
Can you
A) Check your log lines to see whether there are warnings or errors being printed?
B) Give us the "dependencies" section of your package.json?
Good news: things suddenly started working again.
Bad news: I'm not sure why.
Basically I just did a whole bunch of npm installs and updates for everything I could.
A) The error I was getting (located inside the logs tab of the functions tab of the firebase console) was this:
Error: Can't determine Firebase Database URL.
at FirebaseDatabaseError.Error (native)
at FirebaseDatabaseError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:39:28)
at new FirebaseDatabaseError (/user_code/node_modules/firebase-admin/lib/utils/error.js:190:23)
at DatabaseService.ensureUrl (/user_code/node_modules/firebase-admin/lib/database/database.js:74:15)
at DatabaseService.getDatabase (/user_code/node_modules/firebase-admin/lib/database/database.js:52:26)
at FirebaseApp.database (/user_code/node_modules/firebase-admin/lib/firebase-app.js:236:24)
at FirebaseNamespace.fn (/user_code/node_modules/firebase-admin/lib/firebase-namespace.js:296:42)
at exports.enqueue.functions.https.onRequest (/user_code/index.js:18:27)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:26:41)
at /var/tmp/worker/worker.js:686:7
B) Here are the dependencies of the package.json file within the functions folder of my git repo:
"firebase-admin": "~5.8.1",
"firebase-functions": "^1.0.0"
Odd. Can you try the following lines after including firebase-functions?
const fs = require('fs');
console.log('FIREBASE_CONFIG is', process.env.FIREBASE_CONFIG);
console.log('GCLOUD_PROJECT is', process.env.GCLOUD_PROJECT);
console.log('runtime config is', require('./.runtimeconfig.json'));
(If you have other secrets in runtime config, you'll want to cut those out before sharing)
So runtimeconfig.json doesn't exist, but the output of the other two logs look normal:
GCLOUD_PROJECT is [project name]
FIREBASE_CONFIG is {"projectId":"[project name]","databaseURL":"https://[project name].firebaseio.com","storageBucket":"[project name].appspot.com"}
Oh. I read too fast and missed the part where everything started working again. I suspect that when you reran npm install, you upgraded either to the 1.0 version of firebase-functions, which sets the FIREBASE_CONFIG variable or to a newer version of firebase-admin, which can initialize from that variable. If things are now working, you shouldn't need to worry about regressing.
I had the same issue solved it like this
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);
@Shery11 That is only valid on versions < 1.0
I also got the Can't determine Firebase Database URL error when using TypeScript.
I solved it by using @Shery11 's solution:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);
This is a fresh project scaffolded today with the CLI. Here are my dependencies:
"dependencies": {
"firebase-admin": "^5.8.2",
"firebase-functions": "^0.8.1"
},
"devDependencies": {
"typescript": "^2.5.3"
},
Why is the CLI configuring 0.8.1 instead of 1.1.0 ?
You must not have the latest CLI. firebase --version should print 3.19.3
Thanks @laurenzlong that was it.
It's weird that the dependencies' versions are tied to the CLI version. I just scaffolded a TypeScript project and I got 1.0.3 instead of the latest 1.1.0.
The other thing that confused me is that I've been already using v1 of firebase-functions for months with previous CLI versions.
That's because the CLI hardcodes templates for "firebase init", for example https://github.com/firebase/firebase-tools/blob/master/templates/init/functions/typescript/package.lint.json. So what gets initialized depends on your CLI version.
Thanks for the info.
Not such a great idea to hardcode templates if you ask me, but it's good to know.
Yeah I've been meaning to make it dynamically pull in the latest versions from npm... but it keeps falling behind on my to do list. Great chance to make a PR if anyone has some time on their hand!
Just want to add that adding firebase functions before initializeApp() worked for me.
The problem:
'use strict';
global['firebase_admin'] = require('firebase-admin');
firebase_admin.initializeApp();
The solution
'use strict';
global['firebase_functions'] = require('firebase-functions');
global['firebase_admin'] = require('firebase-admin');
firebase_admin.initializeApp();
Most helpful comment
I had the same issue solved it like this
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);