I'm tryin to do a simple function about Reading Data Once. but I get error like this:
index.js
var firebase = require("firebase");
var config = {
apiKey: "some api key",
authDomain: "fitto-exercise.firebaseapp.com",
databaseURL: "https://fitto-exercise.firebaseio.com",
projectId: "fitto-exercise",
storageBucket: "fitto-exercise.appspot.com",
messagingSenderId: "some number"
};
firebase.initializeApp(config);
and the search.js is here:
var firebase = require('.');
var admin = require("firebase-admin");
var db = admin.database();
var ref = db.ref("exercises/exercise");
ref.once("58.967", function(data) {
console.log("Got it!");
});
index.js and search.js in the same directory
I'm still inexperienced about this stuff maybe there are some noob mistakes.
This is my database looks like:
A couple problems here. If you're trying to require() some other file, it needs to have an export defined. In index.js (if that's what you're trying to require), doesn't have an export.
I'd suggest using just a single file for now, until you get your most basic code to work.
Also, according to the API documentation for once(), the method accepts, as its first argument:
One of the following strings: "value", "child_added", "child_changed",
"child_removed", or "child_moved."
"58.967" isn't one of them, and I don't know what you were intending to do there. But you probably want to use "value" to get the value of a child in the database.
Related
Hello I am running a small script that I want to run locally since max timeout of firebase functions is 9 minutes and that is not enough for me (I have to run a large scale update on data types).
So the code is basically:
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
db.collection('users')
.get()
.then(querySnapshot => {
querySnapshot.docs.forEach(doc => {
// update doc
});
});
But querySnapshot.docs has 0 elements. I checked the same code in functions and it works properly. What could be the cause of this? If this is not possible are there any workarounds where I can bypass timeout using cloud functions?
Firebase is initialized correctly both in my machine and directory. I tried a clean initialized directory too. Same code when passed to an firebase function endpoint and ran once works perfectly fine.
If you run a script written with the Admin SDK locally on your computer you need to initialize the SDK with an exported service account key file as explained in the doc.
The doc details how to:
Generate a private key file in JSON format from the Firebase console
Set an environment variable to the file path of the JSON file that contains your service account key.
Then you can do as follows:
const admin = require('firebase-admin');
admin.initializeApp({
credential: applicationDefault()
});
const db = admin.firestore();
db.collection('users')
.get()
.then(querySnapshot => {
return Promise.all(querySnapshot.docs.map(doc => doc.ref.update( {...} ))):
})
.then(() => {...})
.catch(...)
Note that to update several docs within a loop via the asynchronous update() method you'll need to use Promise.all(), as shown above.
When I initialized like this everything seemed to work fine. The reason why applicationDefault doesn't work is I think because doc says it works in google environments.
const admin = require('firebase-admin');
var serviceAccount = require('path/to/key.json')
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
I'm working an app that need to access the firebase database on both client-side (to catch "on" event to grab recently added data) and server-side (to add record to the database). I'm not sure that I did it correctly that use 2 db instances are required on both client and server OR create 1 on the server and use it on the client cause I got a warning on the local side saying that Firebase is already defined in the global scope.
This is how I declare the db instance on server-side, this works perfectly fine:
var admin = require("firebase-admin");
var serviceAccount = require("../config/sterminal-0000-firebase-adminsdk-bvuit-ce5ee771bc.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://sterminal-0000.firebaseio.com"
});
module.exports.admin = admin;
...
const {admin} = require('../extra/firebase');
let db = admin.database();
This is how I declare the db instance on client-side:
Include the libs to pug template
script(src="https://www.gstatic.com/firebasejs/7.14.2/firebase-app.js")
script(src="https://www.gstatic.com/firebasejs/7.14.2/firebase-database.js")
script(src="/javascripts/local.js" crossorigin="anonymous")
And in local script:
var firebaseConfig = {
apiKey: "AIzaSyCkip7lcHNNodJNhrO5n0Hog5Kvs100000",
authDomain: "sterminal-00000.firebaseapp.com",
databaseURL: "https://sterminal-00000.firebaseio.com",
projectId: "sterminal-8bf73",
storageBucket: "sterminal-00000.appspot.com",
messagingSenderId: "961511900000",
appId: "1:96151100000:web:f3cec40f38f7b7d4000000"
};
firebase.initializeApp(firebaseConfig);
firebase.database().ref("messages").on("child_added", function (snap) {
console.log(snap.val().message);
}); // ----> DOES NOT WORK
I got a warning on local-side:
logger.ts:115 [2020-04-27T18:43:48.559Z] #firebase/app:
Warning: Firebase is already defined in the global scope. Please make sure
Firebase library is only loaded once.
Yes, you can access Firebase Realtime Database from both client-side Node.js and server-side Node.js. But the SDK are separate, and you can't include both of them in a single project. The latter seems to be what is leading to the error you now have.
I am using Flutter to build an app that accesses the Firebase database. All good from the Flutter side....but I am new to Node.js and Cloud Functions. I am trying to create a Node.js function to react to a deletion event of a record on one Firebase Database node and then delete records from two other Firebase Database nodes and image files from Firestore.
I am reacting to the trigger event with a functions.database.onDelete call, no problem, but falling at the very next hurdle i.e.trying to read admin.database to get a snapshot.
I have created a dummy function that uses .onUpdate to pick up a trigger event (don't want to keep having to recreate my data as I would if I used .onDelete) and then tries to read my Firebase Database to access a different node. The trigger event is picked up fine but I don't seem to have a database reference Url to do the read...yet it is the same database. Output on the console log from a call to process.env.FIREBASE_CONFIG shows the Url is present.
The included function code also has commenting to show the various outputs I get on the console log.
I am going crazy over this.....PLEASE can anyone tell me where I am going wrong. Been searching Google, Stackoverflow, Firebase docs for the last two days :-(
const admin = require("firebase-admin"); // Import Admin SDK
const functions = require("firebase-functions"); // Import Cloud Functions
admin.initializeApp({
credential: admin.credential.cert(
require("./user-guy-firebase-adminsdk.json")
)
});
exports.testDeleteFunction = functions.database
.ref("/user-guys/{userGuyId}")
// Using .onUpdate as I don't want to keep restoring my data if I use .onDelete
.onUpdate((snapshot, context) => {
const userData = snapshot.after.val();
const userId = userData.userId;
console.log('userId: ' + userId); // Gives correct console log output: userId: wajzviEcUvPZEcMUbbkPzcw64MB2
console.log(process.env.FIREBASE_CONFIG);
// Gives correct console log output:
// {"projectId":"user-guy","databaseURL":"https://user-guy.firebaseio.com","storageBucket":"user-guy.appspot.com","cloudResourceLocation":"us-central"}
// I have tried each of the four following calls and received the console log message as indicated after each.
//
// var root = admin.database.ref(); // Console Log Message: TypeError: admin.database.ref is not a function
// var root = admin.database().ref(); // Console Log Message: Error: Can't determine Firebase Database URL.
// var root = admin.database.ref; // Fails at line 31 below with the message indicated.
// var root = admin.database().ref; // Console Log Message: Error: Can't determine Firebase Database URL.
console.log(root.toString); // Console Log Message: TypeError: Cannot read property 'toString' of undefined.
// This is intended to read a chat thread for two users but processing never gets here.
var database = root.child('chats').child('0cSLt3Sa0FS26QIvOLbin6MFsL43GUPYmmAg9UUlRLnW97jpMCAkEHE3');
database
.once("value")
.then(snapshot => {
console.log(snapshot.val());
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
return null; // Will do stuff here once working.
});
Error messages shown in code comments.
If you want to use the configuration in FIREBASE_CONFIG, you should initialize the Admin SDK with no parameters:
admin.initializeApp();
This will use the default service account for your project, which should have full read and write access to the database.
You need to add your database url in admin.initializeApp
admin.initializeApp({
databaseURL:"your_database_url"
});
select Realtime Database in firebase and copy your url add in settings in fire config or watch this video https://www.youtube.com/watch?v=oOm_9y3vb80
config example
const config = {
apiKey: "",
authDomain: "",
projectId: "",
databaseURL: "https://youUrl.firebaseio.com/",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
};
See:
https://firebase.google.com/docs/admin/setup#initialize_without_parameters
https://firebase.google.com/docs/functions/database-events
Try initialize without parameters.
The SDK can also be initialized with no parameters. In this case, the SDK uses Google Application Default Credentials and reads options from the FIREBASE_CONFIG environment variable. If the content of the FIREBASE_CONFIG variable begins with a { it will be parsed as a JSON object. Otherwise the SDK assumes that the string is the name of a JSON file containing the options.
const admin = require("firebase-admin"); // Import Admin SDK
const functions = require("firebase-functions"); // Import Cloud Functions
admin.initializeApp();
Same issue 3 years later...
After DAYS! I found out all of the Flutter documents have code for Firestore instead of Firebase.
Basically there are two products. Firestore Database, and Real-time Database. You are calling the Real-time Database methods, but probably have a Firestore database.
Try admin.firebase().ref('/some_collection').push();
Basically everywhere you're calling .database(), replace it with .firebase() if you are using Firebase. Yes, the Flutter tutorials are mis-leading!!!
I have a NodeJS script in which I'm watching trees in my Firebase database to see if an entry has been added/changed/removed via the child_added, childed_changed, and child_removed properties of the Firebase Admin .on() function in order to sync entries with my Algolia database.
The problem is that when I add/change/remove an item on these trees, the functions themselves never get fired.
However, when I start the script, I also have a .once('value', initialImport) function I call that works fine.
So for example, here is my relevant child_added code in my NodeJS script:
var dotenv = require('dotenv');
var firebaseAdmin = require("firebase-admin");
var algoliasearch = require('algoliasearch');
// load values from the .env file in this directory into process.env
dotenv.load();
var serviceAccount = require("./serviceAccountKey.json");
firebaseAdmin.initializeApp({
credential: firebaseAdmin.credential.cert(serviceAccount),
databaseURL: process.env.FIREBASE_DATABASE_URL
});
var database = firebaseAdmin.database();
var algolia = algoliasearch(process.env.ALGOLIA_APP_ID, process.env.ALGOLIA_API_KEY);
var users = algolia.initIndex('users');
var bandsRef = database.ref("/social/bands");
bandsRef.on('child_added', addOrUpdateBandIndexRecord);
/**
* Add or update a band index record
*/
function addOrUpdateBandIndexRecord(dataSnapshot) {
// Get Firebase object
var firebaseObject = dataSnapshot.val();
// Specify Algolia's objectID using the Firebase object key
firebaseObject.objectID = dataSnapshot.key;
// Add or update object
bands.saveObject(firebaseObject, function(err, content) {
if (err) {
throw err;
}
console.log('Firebase<>Algolia band object saved', firebaseObject.objectID);
});
}
This never runs :/ Is there something I'm doing wrong? This used to work once upon a time.
UPDATE: The issue I was having was that I was also calling a .once() on the ref that I was adding the .on('child_added') and this was causing a conflict. Once I removed the code for .once(), it solved the syncing issue. In order to do an initial import, you'll most likely want that code in a separate node file. This is what worked for me, anyway.
I start my node with "node firebasedb.js". My firebasedb.js contains this code:
var admin = require("firebase-admin");
var serviceAccount = require("service_account.json");
// Initialize Firebase
var config = {
credential: admin.credential.cert(serviceAccount),
apiKey: "<api key>",
authDomain: "<auth domain>",
databaseURL: "<database url>",
storageBucket: "<storage bucket>",
};
admin.initializeApp(config);
When I run node, I am in the directory where the .json file exists.
But it says
Error: Cannot find module 'service_account.json'
You are missing the relative portion of the required path. That is, you should doing something like this:
var serviceAccount = require("./service_account.json");
If it's not a relative path, require will be looking in node_modules for a module named service_account.json.
The problem is that the TypeScript compiler does not know about json files. You can tell the compiler about them by adding the following declaration to your typings file.
declare module "*.json" {
const value: any;
export default value;
}
You can then import json with:
import * as serviceAccount from './service-key.json';
If you do not already have a typings file setup you will need to create one and then tell tsconfig.json about it by adding it to include or files:
"include": [
"./index.d.ts"
],