I'm using the Firebase emulator in order to test my Cloud Function. The code I'm trying to execute is:
import * as functions from "firebase-functions";
const fetch = require('node-fetch');
export const newZipCode = functions.database.ref('/zipCodes/{zipCode}').onCreate(async (snapshot, context) => {
const api = await fetch(`https://api.papapi.se/lite/?query=${context.params.zipCode}&format=json&apikey=xxx`);
const json = await api.json();
console.log(context.params.zipCode);
if (api.ok) {
snapshot.ref.update({
latitude: json.results[0].latitude,
longitude: json.results[0].longitude
});
} else {
console.log(${api.status}));
}
});
However, when I try to run the Firestore- and Functions emulators, I receive this error message:
"Missing expected firebase config value databaseURL, config is actually{"storageBucket":"xxxx-yyyy.appspot.com","projectId":"xxxx-yyyy"}"
Shouldn't Cloud Functions and Firestore emulators be able to communicate right of the box? If not, what needs to be done in order to get the emulators running? FYI, I'm running Node.js 14 and Firebase version 9.6.1.
The problem is that you are starting the Firestore emulator when you should start the Database emulator instead, as you are using the Realtime Database onCreate() event handler.
Since you are starting the Firestore emulator, you probably don't have a Realtime Database created in the Firebase console so you get the "Missing expected firebase config value databaseURL..." error. You can create one following the steps of the public documentation.
Or if you want to use Cloud Firestore you need to modify your code to use the Firestore onCreate() event handler instead.
import * as functions from "firebase-functions";
const fetch = require('node-fetch');
export const newZipCode = functions.firestore.document('/zipCodes/{zipCode}').onCreate(async (snapshot, context) => {
const api = await fetch(`https://api.papapi.se/lite/?query=${context.params.zipCode}&format=json&apikey=xxx`);
const json = await api.json();
console.log(context.params.zipCode);
if (api.ok) {
snapshot.ref.update({
latitude: json.results[0].latitude,
longitude: json.results[0].longitude
});
} else {
console.log(${api.status}));
}
});
Related
I am using Firebase SDK's within Node-red (as specified in NPM docs they can be used for IoT devices with NODE.js).
I can use all of the CRUD methods with Firebase RealtimeDatabase.
With Firebase Firestore I can only use READ and DELETE functionality.
SET and UPDATE results in weird errors that I couldn't find answers
anywhere on the internet.
I am importing Firebase SDK's through require() inside settiings.js and functionGlobalContext so I can access them in Node-red functions:
functionGlobalContext: {
firebase: require('firebase/app'),
firebaseDatabase: require('firebase/database'),
firebaseFirestore: require('firebase/firestore'),
// os:require('os'),
// jfive:require("johnny-five"),
// j5board:require("johnny-five").Board({repl:false})
},
First I initialize my whole Firebase project with this code (and everything initializes fine without errors):
//Load data from Global contexta
const firebase = global.get('firebase');
const firebaseDatabase = global.get('firebaseDatabase');
const firebaseFirestore = global.get('firebaseFirestore');
const firebaseConfig = {
//my Firebase credentials
};
//Set up Firebase
const app = firebase.initializeApp(firebaseConfig);
const database = firebaseDatabase.getDatabase();
const firestore = firebaseFirestore.getFirestore();
//Save the database reference to Global context
global.set('app', app);
global.set('database', database);
global.set('firestore', firestore);
And here I am trying basic SET operation with Firestore:
const ft = global.get('firebaseFirestore');
const firestore = global.get('firestore');
const frankDocRef = ft.doc(firestore, "users", "frank");
await ft.setDoc(frankDocRef, {
name: "Frank",
age: 12
});
Unfortunately even though this code is ctrl+c ctrl+v from Firestore docs I get this error:
"FirebaseError: [code=invalid-argument]: Function setDoc() called with invalid data. Data must be an object, but it was: a custom Object object (found in document users/frank)"
When I use the same code inside a web app everything works fine.
There has to be something going on under the hood with Node-red
I tried creating the object using various methods and all of them resulted in the same error.
Does anybody have any idea what could be going wrong here?
I am making an app in flutter and using cloud function in firebase to update a number in Firestone,
index.js
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access Cloud Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
exports.getRandomNumbers=functions.https.onCall((context)=>
{
const numbers=admin.firestore().collection('RandomNumbers').document('CurrentRandomNumber');
return numbers.add({
RandomNumber=5;
});
});
and this is the function
onPressed: () async{
final HttpsCallable callable = CloudFunctions.instance.getHttpsCallable(
functionName: 'getRandomNumbers',
);
await callable.call().catchError((error){
print('$error');
});
},
The error that is coming is
PlatformException(functionsError, Cloud function failed with exception., {code: NOT_FOUND, details: null, message: NOT_FOUND})
I also found these in my log which I may think is the reason of this
W/DynamiteModule(12544): Local module descriptor class for providerinstaller not found.
I/DynamiteModule(12544): Considering local module providerinstaller:0 and remote module providerinstaller:0
W/ProviderInstaller(12544): Failed to load providerinstaller module: No acceptable module found. Local version is 0 and remote version is 0.
NOTE
I have updated my Google Play services to the latest.
I have taken permission of the INTERNET in the manifest file.
redownloaded the .json file and checked
The code in your Callable Cloud Function is not correct.
By doing
const numbers = admin.firestore().collection('RandomNumbers').document('CurrentRandomNumber');
you are declaring a DocumentReference. A DocumentReference does not have an add() method.
If you want to get the value of a specific field of this document you should use the asynchronous get() method, as follows:
exports.getRandomNumbers = functions.https.onCall((data, context) => {
const numbers = admin.firestore().collection('RandomNumbers').document('CurrentRandomNumber');
return numbers.get().then(documentSnapshot => {
if (documentSnapshot.exists) {
console.log('Document retrieved successfully.');
const aNumber = documentSnapshot.data().aNumber;
// Do something
// ...
return null; // or return the promise returned by an asynchronous method call,
// see https://firebase.google.com/docs/functions/terminate-functions?authuser=1
} else {
console.log('Document does not exist.');
return null;
}
})
});
If you want to increment the value of a specific field of the Firestore doc, you should probably use a Transaction (it depends on your exact use case).
I'm using firebase functions to run the code for my flutter app. That sends a push notification to my app. I want to get the token. But I'm getting null value at snap.val(). Here how my code looks like:
const functions = require('firebase-functions');
var admin = require("firebase-admin");
admin.initializeApp();
var db = admin.database();
exports.CreateTicket = functions.firestore
.document('tickets/{username}')
.onCreate((snapshot, context) => {
console.log(snapshot.data().clientUid);// this one working fine.
var ref = db.ref("token/BX3jXKVpOkRa80SIKb7jPwfbU0c2/");
ref.once("value", (snap) => {
console.log(snap.val()); // this one getting null,
});
});
Your code is querying Realtime Database, but the screenshot here is showing Firestore. These are completely different database systems. Your database query is simply finding nothing, because there is no data at the location of your query.
You will have to write your code using the Firestore APIs for nodejs to read the document you have shown here.
const functions = require('firebase-functions');
import iapReceiptValidator from 'iap-receipt-validator';
const password = 'abcdefghijkac64beb900889e1'; // Shared Secret from iTunes connect
const production = false; // use sandbox or production url for validation
async validate(receiptData) {
try {
const validationData = await validateReceipt(receiptData);
// check if Auto-Renewable Subscription is still valid
validationData['latest_receipt_info'][0].expires_date > today
} catch(err) {
console.log(err.valid, err.error, err.message)
}
}
exports.validateReceipt = functions.https.onRequest((req, res) => {
const validateReceipt = iapReceiptValidator(password, production);
}
This is what I have so far. I am using this external library. I am using firebase cloud functions and I am on flame plan. I want to make POST request to send receipt JSON object to app store server for auto-renewable purchase verification. I am not sure how to go forward with this. Can i please get some help in regards to structuring my cloud function. The firebase documentation isn't very helpful.
Appreciate any help!
So I have written code which should change a certain value in the database. I would use cron-jobs to trigger it in every 24h, but there is something wrong with my code.
const functions = require('firebase-functions');
exports.resetPicksStatus = functions.https.onRequest((req, res) => {
.ref('/users/{userId}')
.onWrite(event => {
const status = event.data.val()
if (status.resetted) {
return true
}
console.log("Resetting status for " + event.paramas.userId)
status.resetted = true
status.picksDone = resetToNil(status.picksDone)
return event.data.ref.set(status)
})
})
function resetToNil(s) {
var resetValue = s
resetValue = resetValue.replace(/\b1\b/ig, "0")
return resetValue
}
It looks like you're trying to put a Realtime Database trigger inside your HTTP trigger, which won't have the outcome you're looking for. Instead of using a database trigger, use the Firebase Admin SDK to access the database from within the HTTP trigger.
In your code, add
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const ref = admin.database().ref();
And use ref to access the database.
Check out the Admin SDK documentation here.
Here are some samples of Cloud Functions, some of which show the Admin SDK.
Here's a video showing how to use the Admin SDK
Here's a video on timing Cloud Functions