Platform exception while using google cloud function in flutter? - firebase

I am making an app using firebase cloud function but every time I use it there is an exceptions
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(functions.config().firebase);
exports.addUser = functions(region:'asia-south1').https.onCall((data, context) => {
const users = admin.firestore().collection('log');
return users.add({
/* name: data["name"],
email: data["email"]*/
description: "test"
});
});
and this is the function
final HttpsCallable callable= new CloudFunctions(region:"asia-south1" ).getHttpsCallable(
functionName: "addUser",
);
await callable.call().catchError((e)=>print(e));
and this is the exception
PlatformException(functionsError, Cloud function failed with exception., {code: NOT_FOUND, details: null, message: NOT_FOUND})

Related

Testing Firebase Cloud Functions: Using admin SDK with jest

What is the best way to use the Firebase admin SDK in jest script to get Firestore information?
I am unable to use the admin SDK in my jest scripts. Running admin.firestore() throws:
Total timeout of API google.firestore.v1.Firestore exceeded 600000 milliseconds before any response was received.
My code:
let issueRefundWix: HttpsCallable<unknown, unknown>,
initApp = async () => {
const serAcc: ServiceAccount = await import(GOOGLE_APPLICATION_CREDENTIALS);
const app = initializeApp(firebaseConfig);
const functions = getFunctions(app, "us-central1");
const db = getFirestore(app);
const auth = getAuth(app);
admin.initializeApp({
credential: admin.credential.cert(serAcc),
storageBucket: "gs://**.appspot.com/",
});
return {
app: app,
functions: functions,
db: db,
auth: auth,
};
};
beforeAll(async () => {
const app = await initApp();
const functions = app.functions;
issueRefundWix = httpsCallable(functions, "issueRefundWix");
db = admin.firestore();
uid = await createWixUser();
exampleSubscription.wixId = uid;
console.log("Finished beforeAll()");
});
This set up works fine when I am running tests on the Firebase Emulator. Can I test functions the same on the emulator as when they are deployed? All tests work fine if I remove any dependencies on admin.firestore().
What is the best way to use the admin SDK to query firestore in jest tests?
Thank you

Firebase Cloud Function not executing Flutter

I have the following function in my index.ts file:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);
const db = admin.firestore();
const fcm = admin.messaging();
export const sendToDevice = functions.firestore
.document('orders/{orderId}')
.onCreate(async snapshot => {
print("aa")
console.log("osakosak");
const order = snapshot.data();
const querySnapshot = await db
.collection('users')
.doc(order.ustaID)
.collection('tokens')
.get();
const tokens = querySnapshot.docs.map(snap => snap.id);
const payload: admin.messaging.MessagingPayload = {
notification: {
title: 'New Order!',
body: `you sold a ${order.day} for ${order.time}`,
click_action: 'FLUTTER_NOTIFICATION_CLICK'
}
};
return fcm.sendToDevice(tokens, payload);
});
However, when the new document gets added into the order collection, this doesn't get triggered. Even the print and console.log don't work. I tried putting print and console log before export, and it still didn't fire.
Based on your comments ("It depends on cloud_firestore in pubspec.yaml"), it seems that you didn't deploy your Cloud Function correctly.
As a matter of fact, Cloud Functions are totally independent from your Flutter app (your front-end). It is a back-end service. You should deploy it with the Firebase CLI, see the doc. Note that the code shall be in the Firebase Project, not in your Flutter project.

using Cloud Firestore in cloud function

Cloud Function Documentation says
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();
I am using Cloud Firestore, not Realtime Database. How do I access it?
Use admin.firestore() like for example:
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = requi re('firebase-functions');
// The Firebase Admin SDK
const admin = require('firebase-admin');
admin.initializeApp();
//Write a function that uses Firestore, e.g.:
exports.anHttpCloudFunction = functions.https.onRequest((req, res) => {
admin.firestore().collection('XYZ').doc('ABC').set(....)
.then(() => {
res.send({ msg: 'Success' });
})
.catch(err => {....})
});

Dialogflow - Fulfillment Inline Editor(Firebase) is timeout

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.

Creating a document in firestore using cloud functions

After authenticating a user in my app i want to create a cloud functions that creates a user profile document for them in my firestore userProfile collection.
This is my entire index.js file for the cloud function
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
//function that triggers on user creation
//this function will create a user profile in firestore database
exports.createProfile = functions.auth.user().onCreate(event => {
// Do something after a new user account is created
return admin.firestore().ref(`/userProfile/${event.data.uid}`).set({
email: event.data.email
});
});
Here is the error i am receiving
TypeError: admin.firestore(...).ref is not a function
at exports.createProfile.functions.auth.user.onCreate.event (/user_code/index.js:13:30)
at Object.<anonymous> (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:59:27)
at next (native)
at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:53:36)
at /var/tmp/worker/worker.js:695:26
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
In the firestore cloud database I have a collection called userProfile where a document should be created with the unique id given to a user after authentication
admin.firestore() returns an instance of a Firestore object. As you can see from the API docs, the Firestore class doesn't have a ref() method. You're probably confusing it with the Realtime Database API.
Firestore requires you to organize documents within collections. To reach into a document, you could do this:
const doc = admin.firestore().doc(`/userProfile/${event.data.uid}`)
Here, doc is a DocumentReference. You can then set the contents of that document like this:
doc.set({ email: event.data.email })
Be sure to read the Firestore documentation to understand how to set up Firestore - there are many places where it's different than Realtime Database.
Here is my code. When I will create the new user below function will run.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.createProfile = functions.auth.user().onCreate((user) => {
var userObject = {
displayName : user.displayName,
email : user.email,
};
return admin.firestore().doc('users/'+user.uid).set(userObject);
// or admin.firestore().doc('users').add(userObject); for auto generated ID
});

Resources