messaging.sendMulticast is not a function - node.js

I get the above error when I try and send messages to devices:
let functions = require("firebase-functions");
const admin = require("firebase-admin");
var serviceAccount = require("./configs.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://pushmessage-bd1eb.firebaseio.com"
});
const db = admin.firestore();
exports.getUsers = functions.https.onRequest(async (req, res) => {
db.collection("users")
.get()
.then(snapshot => {
const messaging = admin.messaging();
let registrationTokens = [];
snapshot.forEach(doc => {
let id = doc.id;
registrationTokens.push(id);
});
console.log(registrationTokens);
// process the tokens
const message = {
data: { title: "Testing", body: "Test" },
tokens: registrationTokens
};
messaging.sendMulticast(message).then(response => {
console.log(
response.successCount + " messages were sent successfully"
);
});
});
});

sendMulticast wasn't introduced into the Firebase Admin SDK until very recently. Try upgrading your firebase-admin dependency to the latest (npm install firebase-admin#latest).

Related

How to get data from both Authentication and firestore at same time?

I am doing a firebase project, with Node JS admin SDK
In my firebase:
In Authentication->users->(list of users with information phoneNumber, signedInDate, User UID)
In Firestore Databases->users(collection)->name, email
I want to read the data and display it as table,
i.e., phone, user UID,name,email in a table
I have written code like this, until now:
const admin = require('firebase-admin');
const serviceAccount = require("C:/Users/santo/Downloads/adminsdk.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
let fs = admin.firestore();
let auth = admin.auth();
const listAllUsers = async (nextPageToken) => {
try {
let result = await auth.listUsers(100, nextPageToken);
result.users.forEach((userRecord) => {
console.table(userRecord.toJSON().uid);
console.table(userRecord.toJSON().phoneNumber);
});
if (result.pageToken) {
listAllUsers(result.pageToken);
}
} catch(ex) {
console.log('Exception listing users:', ex.message);
}
}
async function start() {
const santosh = await fs.collection('users').doc('ANCyBKH2z5jKm1xZx6vegFUr2').get();
//console.table([santosh.data()]);
await listAllUsers();
}
start();

Firebase function works when deployed but not locally

I have a function that just fetches the data from my firebase and displays it. This works perfectly when deployed, but not locally.
I've attached my code just in case, but seeing as it works when deployed, I dont think that will be the problem, also its copy pasted from freecodecamp tutorial.
Directory is as follows:
firebase folder
|functions
||APIs
|||todos.js
||util
|||admin.js
||index.js
Also, the local version does have an output, its just the empty array initialised in todos.js line 9.
//todos.js
const { db } = require('complete file path');
exports.getAllTodos = (request, response) => {
db
.collection('todos')
.orderBy('createdAt', 'desc')
.get()
.then((data) => {
let todos = [];
data.forEach((doc) => {
todos.push({
todoId: doc.id,
title: doc.data().title,
body: doc.data().body,
createdAt: doc.data().createdAt,
});
});
return response.json(todos);
})
.catch((err) => {
console.error(err);
return response.status(500).json({ error: err.code});
});
};
//admin.js
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
module.exports = { admin, db };
//index.js
const functions = require('firebase-functions');
const app = require('express')();
const {
getAllTodos
} = require('./APIs/todos')
app.get('/todos', getAllTodos);
exports.api = functions.https.onRequest(app);
I also performed export GOOGLE_APPLICATION_CREDENTIALS="path/to/key.json" to no avail.
You initialized the the app without any credentials:
const refreshToken; // Get refresh token from OAuth2 flow
admin.initializeApp({
credential: admin.credential.refreshToken(refreshToken),
databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});
[Reference this site for more information:] https://firebase.google.com/docs/admin/setup/#initialize-without-parameters

The firebase function generates a "timeout", error 304

I am using firebase to validate that the data sent by the client is authentic using a google or facebook token. But when uploading to functions it generates an error.
Function execution took 60003 ms, finished with status: 'timeout'
Function execution took 232 ms, finished with status code: 304
On my home pc it runs me normally. Is what I am doing correct or is there some other way to validate the authenticity of the data
firebase.js
var firebase = require("firebase/app");
require("firebase/auth");
require("firebase/firestore");
var firebaseConfig = {
apiKey: ....,
authDomain: ....,
projectId: ....,
storageBucket: ....,
messagingSenderId: ....,
appId: ....
measurementId: ....
};
let app = null
if (!firebase.apps.length) {
app = firebase.initializeApp(firebaseConfig)
}
const auth = firebase.auth();
const google = new firebase.auth.GoogleAuthProvider();
const facebook = new firebase.auth.FacebookAuthProvider();
module.exports = {auth, google, facebook, firebase}
datos.js
const admin = require("firebase-admin");
var serviceAccount = require("./whatsapp-f91a0-firebase-adminsdk-f4fes-a0490d7a8f.json");
if (!admin.apps.length) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://whatsapp-f91a0.firebaseio.com"
});
}
const db = admin.firestore();
module.exports = db;
Code functions
const db = require('./datos');
const {auth, google, facebook, firebase} = require('./firebase')
module.exports = function (req, res, next) {
if (req.method === 'POST') {
const body = []
req.on('data', (chunk) => {
body.push(chunk)
})
req.on('end', () => {
try {
const event = JSON.parse(body)
let xIdPagina = event.xIdPagina;
let xTokenUser = event.xTokenUser;
let xProveedor = event.xProveedor;
let xMotivoReporte = event.xMotivoReporte;
// Build Firebase credential with the Google ID token.
var credential = google.credential(xTokenUser);
// Sign in with credential from the Google user.
auth.signInWithCredential(credential)
.then(result =>{
if(xMotivoReporte != "" && xTokenUser != "" && xTokenUser != ""){
if(xMotivoReporte != "eliminar"){
let grupos = db.collectionGroup('reportes');
let query = grupos
.where('xIdPagina','=', xIdPagina)
.where('xUserId','=', result.user.uid)
.limit(1)
.select('xUserId')
.get()
.then(querySnapshot => {
const documents = querySnapshot.docs.map(doc => doc.data())
if(documents.length < 1 ){
let grupo = {
xIdPagina: xIdPagina,
xUserId: result.user.uid,
xProveedor: xProveedor,
xEmail: result.user.email,
xMotivoReporte : xMotivoReporte
}
let addDoc = db.collection('facebook_spa').doc(xIdPagina).collection('reportes').add(
grupo).then(ref => {
res.statusCode = 200
});
}
else{
console.log('Errores de aqui');
res.statusCode = 400
}
})
.catch(err => {
console.log('Error getting documents', err);
res.statusCode = 404
});
}else{
let grupos = db.collection('facebook_spa');
let query = grupos.where('xEstado', '==', true)
.where('xId','=', xIdPagina)
.where('xUserId','=', result.user.uid)
.limit(1)
.select('xUserId')
.get()
.then(querySnapshot => {
const documents = querySnapshot.docs.map(doc => doc.data())
if(documents.length != 0){
const res = db.collection('facebook_spa').doc(xIdPagina).delete();
}
else{
res.statusCode = 404
}
})
.catch(err => {
console.log('Error getting documents', err);
res.statusCode = 404
});
}
}
else{
throw Error('reporte');
}
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// ...
});
} catch (error) {
console.log("El error esta aqui: " + error)
res.statusCode = 400
}
finally {
res.end()
}
})
}
}

Firebase function error <admin.auth is not a function at ..>

I'm fairly new to Firebase and Node.js. I have created this function in my Cloud Functions to login users with a custom token:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
var serviceAccount = require("./service-account.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: functions.config().firebase.databaseURL
});
const cors = require('cors')({origin: true});
exports.login = functions.https.onRequest((req, res) => {
cors(req, res, () => {
//doing some validation..
//get password from db and match it with input password
var userRef = admin.firestore().collection('users')
userRef.where('username', '==', username).get()
.then(snapshot => {
if(snapshot.size > 1){
res.status(200).send("Invalid account!");
return;
}
snapshot.forEach(doc => {
var userPass = doc.data().password;
//if password matches, generate token, save it in db and send it
if(userPass && password == userPass){
var uid = doc.data().uid;
var admin = Boolean(doc.data().admin);
var server = Boolean(doc.data().server);
var additionalClaims = {
admin: admin,
server: server
};
admin.auth().createCustomToken(uid, additionalClaims)
.then(function(customToken) {
res.status(200).send("token:" + customToken);
})
.catch(function(error) {
res.status(200).send("Token creation failed!");
});
//save token in db..
}else{
res.status(200).send("Invalid credentials!");
}
});
})
.catch(err => {
res.status(200).send("User authentication failed!");
});
});
});
I used the token generation method in the documentation, but whenever I try to login a user it throws the error:
TypeError: admin.auth is not a function
at snapshot.forEach.doc (/user_code/index.js:128:27)
at QuerySnapshot.forEach (/user_code/node_modules/firebase-admin/node_modules/#google-cloud/firestore/src/reference.js:1012:16)
at userRef.where.get.then.snapshot (/user_code/index.js:110:13)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
What could it be that I'm doing wrong?
This declaration of admin:
var admin = Boolean(doc.data().admin);
is hiding this one:
const admin = require('firebase-admin');
Use a different name, such as:
var docAdmin = Boolean(doc.data().admin);

Cloud Functions for Firebase Notification

I am trying to fire a notification using Cloud Functions for Firebase. I can get it to console log stating a message has been fired, but can't actually get the notification to work in the browser. Can anyone see a flaw?
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.newMessageAlert = functions.database.ref('/messages/{message}').onWrite((event) => {
const message = event.data.val();
const getTokens = admin.database().ref('users').once('value').then((snapshot) => {
const tokens = [];
snapshot.forEach((user) => {
const token = user.child('token').val();
if (token) tokens.push(token);
});
return tokens;
});
const getAuthor = admin.auth().getUser(message.uid);
Promise.all([getTokens, getAuthor]).then(([tokens, author]) => {
const payload = {
notification: {
title: `Hot Take from ${author.displayName}`,
body: message.content,
icon: author.photoURL
}
};
admin.messaging().sendToDevice(tokens, payload).then((resp) =>{
console.log("IT WORKED", resp);
});
});
});

Resources