I've been trying to implement some Cloud Functions that get and post data from Cloud Firestore(I'm using postman). I want to test these locally, however I cannot get the Cloud Firestore emulator to run.
My index.js file
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const express = require("express");
admin.initializeApp();
const app = express();
app.get("/posts", (req, res) => {
admin
.firestore()
.collection("posts")
.orderBy("createdAt", "desc")
.get()
.then((data) => {
let posts = [];
data.forEach((doc) => {
posts.push({
postId: doc.id,
body: doc.data().body,
userHandle: doc.data().userHandle,
createdAt: doc.data().createdAt,
});
});
return res.json(posts);
})
.catch((err) => console.log(err));
});
app.post("/post", (req, res) => {
const newPost = {
body: req.body.body,
userHandle: req.body.userHandle,
createdAt: new Date().toISOString(),
};
admin
.firestore()
.collection("posts")
.add(newPost)
.then((doc) => {
res.json({ message: `document ${doc.id} created successfully` });
})
.catch((err) => {
res.status(500).json({ error: "something went wrong" });
console.log(err);
});
});
exports.api = functions.https.onRequest(app);
I can get data when never i use firebase deploy method using postman.
result for firebase deploy method is response (status:200) [in postman]
However if i try firebase serve or firebase serve --only function . i get like this...
firebase serve
=== Serving from 'C:\Users\Yuvan M\Documents\Visual Studio Code\React\meme-zha\meeme-functions'...
! Your requested "node" version "8" doesn't match your global version "12"
i functions: Watching "C:\Users\Yuvan M\Documents\Visual Studio Code\React\meme-zha\meeme-functions\functions" for Cloud Functions...
+ functions[api]: http function initialized (http://localhost:5000/meeme-zha/us-central1/api)
in above code i can't get response like
i functions : preparing emulate function.
if i use this local address http://localhost:5000/meeme-zha/us-central1/api , this gives me the error like this...
! functions: The Cloud Firestore emulator is not running, so calls to Firestore will affect production.
! External network resource requested!
I use firebase emulator:start - not working.I tried every solution that posted on internet for this kind of problem, also i followed the documentation . still i can't solve it.
Related
I was trying to deploy a cloud function on firebase but I keep getting this error. I deleted all of my logic to console the response and debug but nothing's changed.
I am sure that the problem is not related to permissions because the invocation is allowed for unauthenticated users.
this is the block of my function:
// Firebase config
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const cors = require("cors")({
origin: true
});
admin.initializeApp();
exports.emailMessage = functions.https.onCall((req, res) => {
return cors(req, res, async() => {
console.log(req);
console.log(res);
}).catch(() => {
res.status(500).send("error");
});
});
I'm trying to learn firebase cloud functions and I want to call an API using it but the console log shows that no data is being fetched, even though the function is deployed successfully/
Firebase function:
const functions = require('firebase-functions');
const axios = require('axios');
exports.fetchList = functions.https.onRequest((request, response) =>{
axios.get('https://rallycoding.herokuapp.com/api/music_albums').then((data) =>{
response.send(data)
}).catch((e) =>{
console.log(e)
})
})
App component:
componentWillMount() {
axios({
method:'POST',
url: 'link from the console website',
}).then((data) =>{
console.log(data.data);
}).catch((e) =>{
console.log(e);
})
}
If you want to see that data from the fetchList data logged to the Firebase console, you need to insert a console.log before you send a response.
const dataToLog = axios.get('https://rallycoding.herokuapp.com/api/music_albums')
.then(dataToLog => {
console.log(dataToLog);
response.send(dataToLog);
}).catch // etc.
Also, probably obvious, but of course you'd need to put in the actual function URL endpoint in your component, not the string link from the console website.
Apologies if I'm misunderstanding your question!
I have two firebase functions deployed, one uses functions.https.onRequest (companyRequest) and one uses functions.https.onCall (companyCall). Both do the exact same thing: retrieve a document from firestore (the exact same document from the exact same collection).
Here are the functions:
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
admin.initializeApp(functions.config().firebase);
export const companyRequest = functions.https.onRequest((request, response) => {
const companyId = "VpOVFo82m9ls3aIK7dra";
admin
.firestore()
.collection("company")
.doc(companyId)
.get()
.then(result => {
response.send(result.data());
})
.catch(error => {
response.send(error);
});
});
export const companyCall = functions.https.onCall((data, context) => {
if (context && context.auth) {
console.log(
"AUTH",
context.auth.uid,
context.auth.token.email
);
}
const companyId = "VpOVFo82m9ls3aIK7dra";
admin
.firestore()
.collection("company")
.doc(companyId)
.get()
.then(result => {
return result.data();
})
.catch(error => {
return error;
});
});
I call companyRequest with curl and it works:
> curl https://us-central1-xxxxx.cloudfunctions.net/company
{"name":"Duny Comp."}
I call companyCall from flutter and it fails (on firebase, server site):
Future click() async {
final HttpsCallable callable = CloudFunctions.instance.getHttpsCallable(
functionName: 'companyCall',
);
HttpsCallableResult resp = await callable.call(<String, dynamic>{
'companyId': 'VpOVFo82m9ls3aIK7dra',
});
print(resp.data);
}
the error I get for companyCall is this:
AUTH 3gvfgYJpk2gIgUpkOLxdkdId uuuu#xxxx.com
ERROR: Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information
The error seems quite clear, but why does the unauthenticated call with curl work, but companyCall with firebase authentication via flutter does have a permission problems? In the output you can even see the auth information from the enduser in the flutter app, so he is authenticated.
The question is, why there is a difference between the two? The proposed solutions like Error: Could not load the default credentials (Firebase function to firestore) also feel very strange...
Update:
This is not the same question as in Firebase Cloud Functions: Difference between onRequest and onCall, in this question I ask why there is a difference in the security behaves different between the two different methods. Why do I need to authenticate with an admin account to access the same collection from onCall as I don't need it when access the collection from a onRequest method?
I am testing with Dialogflow using Firebase project.
The Firebase Project is already used as an android backend. (Firestore)
Now, I am trying to attach chatbot.
This github code is what I want.
I create a new Dialogflow Agent, it refers to the Firebase project.
Enable Fullfillment Inline Editor, and I copy&paste a code from upper github code.
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const {WebhookClient} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function writeToDb (agent) {
const databaseEntry = agent.parameters.databaseEntry;
const dialogflowAgentRef = db.collection('dialogflow').doc('agent');
return db.runTransaction(t => {
t.set(dialogflowAgentRef, {entry: databaseEntry});
return Promise.resolve('Write complete');
}).then(doc => {
agent.add(`Wrote "${databaseEntry}" to the Firestore database.`);
}).catch(err => {
console.log(`Error writing to Firestore: ${err}`);
agent.add(`Failed to write "${databaseEntry}" to the Firestore database.`);
});
}
let intentMap = new Map();
intentMap.set('WriteToFirestore', writeToDb);
agent.handleRequest(intentMap); // Here is index.js:51
});
This is very simple.
It just writes a text into the Firestore.
That's all.
I deployed this fulfillment and linked to an Intent.
In case of first conversation after deploy, I can find below log in Firebase Cloud Functions.
Error: No handler for requested intent
at WebhookClient.handleRequest (/user_code/node_modules/dialogflow-fulfillment/src/dialogflow-fulfillment.js:317:29)
at exports.dialogflowFirebaseFulfillment.functions.https.onRequest (/user_code/index.js:51:9)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:57:9)
And after some times, when I retry again, I can find below logs in the Firebase Cloud Functions.
dialogflowFirebaseFulfillment - Function execution took 60002 ms, finished with status: 'timeout'
I don't know what I am missing...
It was my fault.
The key of intentMap should be same with Intent name.
After I fix it, it works fine.
I want to update or creat an object, but i have this error :"TypeError: functions.database is not a function" on the registry of firebase function
this is my code:
const functions = require('firebase-functions');
exports.actualizar = functions.https.onRequest((request, response) => {
const obj = request.body;
const MAC = obj.MAC;
functions.database().ref ('/sensores/{MAC}').update(obj).promise.then(() =>
{
console.log("UpDate Success");
return req.status(200).send("ok");
})
.catch(() => {
functions.database.ref('/sensores'). set(obj).promise.then(() =>{
console.log ("Created Succces");
return req.status(200).send("");
})
.catch(() =>{
console.log("Error");
return req.status(500).send("error");
})
})
});
You can't use the Cloud Functions for Firebase SDK to query the database. It's just used for building the function definition. To query your database or other Firebase products, you need to use the Firebase Admin SDK, or whatever SDK is normally used to do so.
For example, you will see lots of official sample code that starts like this:
const admin = require('firebase-admin'); // this is the Admin SDK, not firebase-functions
admin.initializeApp();
// Then use "admin" to reach into Realtime Database, Firestore, Cloud Storage, etc.