the first try to firebase cloud functions - javascript

I am trying to make my first firebase cloud function.
I want to add the value of name field -which is in 'amr' document -inside ahmed document with the field name newName . I made this function but each time it gives an error or don't show anything
what is the problem in my function
const functions = require('firebase-functions');
const admin=require('firebase-admin');
admin.initializeApp();
exports.myfunc=functions.firestore.document('Users/amr').onWrite((change,context)=>{
const name=change.data().name;
return admin.firestore().document('Users/ahmed').add({newName:name});
});

Change this:
const name=change.data().name;
into this:
const name=change.after.data().name;
to be able to retrieve the data after the write
more info here:
https://firebase.google.com/docs/functions/beta-v1-diff#cloud-firestore

also change
return admin.firestore().document('Users/ahmed').add({newName:name});
to
return admin.firestore().doc('Users/ahmed').add({newName:name});

Related

Can't use variable as field name updateDoc (firebase)

How can i write a variable there? This is React.
${} and ""+"" are not working
Pls i neeed help
const id = 'currentChat[0].
id';
const fn = async () => {
await updateDoc(contactsRef, {
`${id}.chatHistory`: arrayUnion(message),
});};
fn();
If you have an expression, you need to put it inside []. These are called computed property names.
You need to use
[`${id}.chatHistory/`]
Read this.

How to access a const outside of a method (Discord.js Bot development)

So basically, my bot comes with reaction roles and it works pretty efficiently by using partials. One of the checks before assigning the given role, Is to check whether the reaction role is reacted upon the msgID that I defined in my code. (This is useful for servers that have a channel like #reaction-roles and there is always 1 message that stays there for people to react with)
That is working fine. However, I was trying to do something new with my bot where I need the msgID to be saved (because the bot repeats the msg over and over to different people), however since the const of msgID is in the method called bot.on(message) I cannot access the const anywhere outside the method. Is there any way to get around this? Perhaps a way to temp store it in a config file?
I'm not familiar with discord SDK so this is a more general suggestion.
Think if you really need to use const here. I would suggest using let and defining it outside of the function like:
let msgID
bot.on(message, (message) => {
msgID = message.id
})
// now it's available here
use(msgID)
Just keep in mind that const will not work here
You can assign obj to const variable outside the function and assign value to it inside the function and then you can access it outside the function as well.
Remember, when you assign object to a const it is mutable in a sense that you can change its key/values but you cannot assign something else to this variable.
const someObj = {key: null};
function someName() {
someObj.key = "hello";
}
console.log(someObj.key);

Firestore References

i want to add a reference field in a document into Firestore using nodejs but i can't do it.
I wrote this code:
async function pushType(IDType) {
const size = await getID();
const IDClient = (size).toString();
const docRef = firebase.firestore().collection('Clients').doc(IDClient);
await docRef.set({
ID_Type: firebase.firestore().doc('Types/'+IDType).ref,
});
}
async function getID(){
const snapshot = await firebase.firestore().collection('Clients').get();
return snapshot.size;
}
The error is: "Function Document.Reference.set() called with invalid data. Unsupported field value: undefined (found in field ID_Type in document Clients/7)" where 7 is the ID of the document where i want to add the field ID_Type.
Can anyone help me to understand what i'm wrong and how can i fix it? Thank you
Your code firebase.firestore().doc('Types/'+IDType) returns a DocumentReference. As you can see from the API docs, there is no property called ref on that, so it will be undefined. In fact, that DocumentReference is exactly what you want to provide to Firestore here. So just remove ref:
await docRef.set({
ID_Type: firebase.firestore().doc('Types/'+IDType)
});
When you provide a DocumentReference object to a Firestore document like this, it will create a reference type field.

Firebase function .onWrite not working?

Ok, I have looked at similar questions like Firebase function onWrite not being called and thought it was my fault getting the reference, but I have no idea what is happening here with my Firebase functions.
I am just trying to get a function to write to my database when a write has been made to database. I followed the firebase tutorial exactly:
const functions = require('firebase-functions');
// The Firebase Admin SDK to access the Firebase Realtime Database.
//https://firebase.google.com/docs/functions/database-events
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
// const gl = require('getlocation');
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
exports.enterLocation = functions.database.ref('/Users/{name}') //brackets is client param
.onWrite(event => {
// Grab the current value of what was written to the Realtime Database.
// const original = event.data.val();
console.log('SKYLAR HERE:', event.params.name);
// You must return a Promise when performing asynchronous tasks inside a Functions such as
return firebase.database().ref('/Users/{name}').set({ location: 'test loc' });
});
The function is being run, yet in my logs I get a pretty unhelpful error that it is getting the {name} param, and data is definitely written to my database, however my SERVER code is not writing:
I get -
ReferenceError: firebase is not defined at
exports.enterLocation.functions.database.ref
Which makes no sense as it is defined. I just want to add an extra child under the user I create, like I do already with "password"
What am I doing wrong?
Two problems here. First, you haven't defined firebase anywhere in your code. I think you meant to use admin instead to use the Admin SDK.
Second, it looks like you're trying to do variable interpolation into a string to build the name of the ref. Your syntax is wrong here.
I imagine you're trying to say this instead in your last line of code:
return admin.database().ref(`/Users/${name}`).set({ location: 'test loc' });
Note the backticks on the string quotes. That JavaScript syntax lets you use ${exp} to insert the contents of some expression in the string.
It turns out you don't even need to use the admin SDK here. Since you're trying to write back to the same location that triggered the function, you can just use the ref that comes from the event object:
return event.data.adminRef.set({ location: 'test loc' });
instead of this:
return firebase.database().ref('/Users/{name}').set({ location: 'test loc' });
use this:
return admin.database().ref('/Users/{name}').set({ location: 'test loc' });

How to get Firebase Project Name or ID from Cloud Function

I am using Cloud Functions and want to get the project name from within one of my Javascript server files. I know that value is stored in the .firebaserc, but I don't think that file is available on the server, right? I want to do something like this:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.getProjectName(); // or getProjectID()
or
functions.getProjectName();
Thank you #Frank. The answer is:
process.env.GCLOUD_PROJECT.
I'm not sure where the variable process comes from, but this does work to get the project name.
Firebase admin SDK has access to that information for you.
const admin = require('firebase-admin');
const projectId = admin.instanceId().app.options.projectId
This worked for me. (node 10)
const FIREBASE_CONFIG = process.env.FIREBASE_CONFIG && JSON.parse(process.env.FIREBASE_CONFIG);
const projectId = FIREBASE_CONFIG.projectId;
try this :
const projectId = admin.instanceId().app['options_'].credential.projectId
For cloud functions running on newer versions of Node:
import firestore from "#google-cloud/firestore";
const client = new firestore.v1.FirestoreAdminClient();
const projectId = await client.getProjectId();
From the Firebase docs:
process.env.FIREBASE_CONFIG: Provides the following Firebase project config info:
{
databaseURL: 'https://databaseName.firebaseio.com',
storageBucket: 'projectId.appspot.com',
projectId: 'projectId'
}
Note that since it's a JSON string you need to parse it like this:
const projectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
Alternatively you could use the undocumented firebaseConfig() method from the firebase-functions package in your Cloud Functions, like so:
import { firebaseConfig } from "firebase-functions";
const projectId = firebaseConfig().projectId;
Additionally, Google Cloud Platform (which Firebase runs on top of) will automatically populate the environment variables documented here, depending on which runtime you're using.
The way to retrieve the project ID using admin SDK is
admin.appCheck().app.options.credential.projectId
This also works in headless setups like Docker where the environment variable GOOGLE_APPLICATION_CREDENTIALS is set.
Currently I'm using app.INTERNAL.credential_.projectId.
This is clearly not save, but so far there is no cohesive way to get it (AFAIK)
This is a combination of the answers given above:
function getProjectID() {
return firebaseInstance.options.projectId ||
(firebaseInstance.options.credential && firebaseInstance.options.credential.projectId) || '';
}
Or in TypeScript:
function getProjectID(): string {
return firebaseInstance.options.projectId ||
(firebaseInstance.options.credential && (firebaseInstance.options.credential as unknown as { projectId: string }).projectId) || '';
}
You can use functions.config().firebase.projectId
PS the easiest way to initialize app is admin.initializeApp(functions.config().firebase);

Categories

Resources