Cannot read properties of undefined (reading 'getProvider') in Firebase on NodeJS - node.js

I am developping Firebase Cloud Messaging to my Android from NodeJS server.
Receiving notifications from the FCM console page was successful.
And I implemented server code with FCM Docs. (https://firebase.google.com/docs/admin/setup)
But at runtime I get an error :
[0] TypeError: Cannot read properties of undefined (reading 'getProvider')
[0] at Object._getProvider (/Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/#firebase/app/dist/index.cjs.js:274:26)
[0] at getMessagingInSw (/Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/#firebase/messaging/dist/index.sw.cjs:1522:16)
[0] at sendPushNotification (/Users/scmoon/Desktop/work/CheckRefrigerator/server/routes/product.js:86:5)
[0] at /Users/scmoon/Desktop/work/CheckRefrigerator/server/routes/product.js:54:9
[0] at /Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/mongoose/lib/model.js:4616:16
[0] at /Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/mongoose/lib/utils.js:264:16
[0] at model.<anonymous> (/Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/mongoose/lib/model.js:472:7)
[0] at /Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/kareem/index.js:315:21
[0] at next (/Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/kareem/index.js:209:27)
[0] at /Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/kareem/index.js:182:9
[0] at /Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/kareem/index.js:507:38
[0] at processTicksAndRejections (node:internal/process/task_queues:78:11)
[0] Emitted 'error' event on Function instance at:
[0] at /Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/mongoose/lib/model.js:4618:13
[0] at /Users/scmoon/Desktop/work/CheckRefrigerator/node_modules/mongoose/lib/utils.js:264:16
[0] [... lines matching original stack trace ...]
[0] at processTicksAndRejections (node:internal/process/task_queues:78:11)
There is no 'getProvider' in my code.
I did googling and tried alternative codes
but it still not working.
here is my code.
...
// const { initializeApp } = require('firebase-admin/app');
// const fbapp = initializeApp();
//const { getMessaging } = require("firebase/messaging");
const { getMessaging } = require("firebase/messaging/sw");
const admin = require("firebase-admin");
const serviceAccount = require('../../server/firebase-adminsdk-asdf.json');
const fbapp = admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
const registrationTokens = [
'ePBbqfWEQ7yaj5Zjxera98...',
// …
];
const message = {
notification: { title: req_body.writer, body: req_body.title },
tokens: registrationTokens,
};
getMessaging(fbapp)
// .sendMulticast(message)
.sendAll([message])
.then((response) => {
console.log(response.successCount + ' messages were sent successfully');
});

Not a firebase expert but it seems that sendAll messages expect a token property without a s while sendMulticast accepts tokens.
Which actually makes sense after reading the docs:
token to send each message to 1 target
tokens to send each message to n targets

Related

DiscordJS - Send Message

Im Trying To Send A Message Through DiscordJS
Can Someone Help Me
I Tried This Code
const channel = client.channels.cache.get('example discord guild');
channel.send('content');
But It Doesent Work
index.js
// Credetials
const { token } = require('./json/token.json');
const { guild } = require('./json/guild.json');
const { client } = require('./json/client.json')
// Init
const { Client, Intents } = require('discord.js');
const bot = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_>
bot.login(guild);
console.log("Logged In As DeltaBOT");
const channel = client.channels.cache.get(guild);
channel.send('content');
Error
const channel = client.channels.cache.get(guild);
^
TypeError: Cannot read properties of undefined (reading 'cache')
at Object.<anonymous> (/storage/emulated/0/Download/node/index.js:15:33)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
You should wait for your client to login before attempting to send a message / fetching a channel. You can do this by using the ready event. For example:
bot.on('ready', async () => {
console.log('Logged in as: ' + bot.user.tag);
const channel = await bot.channels.fetch(guild);
await channel.send('content');
})
Another thing I noticed is that you use client instead of bot. client is a json object but you defined your discord bot object as the bot variable. So use the bot variable and not the client one.
Make sure that the guild is a valid guild ID. I don't know what is in your client json file but you don't appear to be using it.

How can I get the secrets in node js application code for already initialized vault?

I have app-id, user-id and nonce, but not vault-token. How can i get the vault-token so i can use the read API to access the secrets in node application dynamically. I have saved DB credentials, which i will be using to connect to while rendering the page. Bellow is my code :
var options = {
apiVersion: 'v1',
user_id: 'abc',
app_id: 'pqr',
endpoint: 'https://abcpqr.com:8200', // default
};
var vault = require("node-vault")(options);
vault.health().then ( (result) => {
var isServerInitialized = result.initialized;
console.log("isServerInitialized :: " + isServerInitialized);
if (isServerInitialized) {
vault.read('/v1/secret/mydb/db/root').then((readResponse) => {
console.log("readResponse ::" + readResponse.data.value);
}
).catch((readError) => console.error("readError:",readError));
}
});
Bellow is the error i am getting :
[0] > node index.js
[0]
[1]
[1] > webapps#0.1.0 start C:\Users\userid\app\webapps
[1] > react-scripts start
[1]
[0] options :: [object Object]
[0] listening to Port 4000
[0] isServerInitialized :: true
[0] readError: ApiResponseError: missing client token
[0] at handleVaultResponse (C:\Users\userid\app\webapps\node_modules\node-vault\src\index.js:58:21)
[0] at processTicksAndRejections (internal/process/task_queues.js:97:5) {
Once you have done vault.init() the token is available in the response;
vault.init({ secret_shares: 1, secret_threshold: 1 })
.then((response) => {
vault.token = response.root_token;
})

Chat application like Slack tutorial

I am following this tutorial here: https://www.youtube.com/watch?v=a-JKj7m2LIo
I got stuck around the 14 minute mark getting the following error message in the terminal:
(node:6248) UnhandledPromiseRejectionWarning: RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: undefined
[0] at ServerResponse.writeHead (_http_server.js:237:11)
[0] at ServerResponse._implicitHeader (_http_server.js:228:8)
[0] at write_ (_http_outgoing.js:616:9)
[0] at ServerResponse.end (_http_outgoing.js:733:5)
[0] at ServerResponse.send (D:\htdocs\mern\react-slack-clone\node_modules\express\lib\response.js:221:10)
[0] at ServerResponse.sendStatus (D:\htdocs\mern\react-slack-clone\node_modules\express\lib\response.js:359:15)
[0] at D:\htdocs\mern\react-slack-clone\server.js:31:13
[0] at processTicksAndRejections (internal/process/task_queues.js:93:5)
[0] (node:6248) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise
which was not handled with .catch(). (rejection id: 1)
[0] (node:6248) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero
exit code
Still learning how to use React and Node, but I think the error is occurring in my server.js file.
My server.js code looks like this:
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const Chatkit = require('pusher-chatkit-server')
const app = express()
const chatkit = new Chatkit.default({
instanceLocator: 'fhdsakfjsdalkfjdsalfjsdlajflsad',
key:
'ruewioqruewfhdsakljfdsaljfsdlakjds483294'
})
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(cors())
app.post('/users', (req, res) => {
const { username } = req.body
chatkit
.createUser({
name: username,
id: username
})
.then(() => res.sendStatus(201))
.catch(error => {
console.log('Error:', error) // updated
/*if(error.error_type === 'services/chatkit/user_already_exists') {
res.sendStatus(200)
} else {
res.sendStatus(error.statusCode).json(error)
}*/
})
})
const PORT = 3001
app.listen(PORT, err => {
if (err) {
console.error(err)
} else {
console.log(`Running on port ${PORT}`)
}
})
Basically, when I submit a name, in the console's network tab, I should see the post, but I am not. The error message is all I get but I'm not sure how to decipher it.
Edit
Added console.log('Error:', error) to the code above and received the following error message in the terminal:
Error: ErrorResponse {
[0] status: 404,
[0] headers: {
[0] 'access-control-expose-headers': 'X-Envoy-Upstream-Service-Time,
Server, Access-Control-Expose-Headers, Access-Control-Max-Age, Date',
[0] 'access-control-max-age': '86400',
[0] 'content-type': 'application/json',
[0] date: 'Tue, 17 Mar 2020 18:07:17 GMT',
[0] server: 'istio-envoy',
[0] 'x-envoy-upstream-service-time': '10',
[0] 'content-length': '209',
[0] connection: 'close'
[0] },
[0] error: 'not_found',
[0] error_description: 'Not found',
[0] error_uri: 'https://docs.pusher.com/errors/not_found'
[0] }
I do not understand what this error message means. I check the URL provided by error_uri, and the message on that page read, "The server couldn't find the requested resource. Please make sure that the name of the resource you are requesting is correct." I am not entirely sure what that means.
Edit 2
I made the following change to app.post in an attempt to produce another terminal error, as follows:
app.post('/users', (req, res) => {
const { username } = req.body
chatkit
.createUser({
name: username,
id: username
})
.then(() => res.sendStatus(201))
.catch(error => {
//console.log('Error:', error)
if(error.error_type === 'services/chatkit/user_already_exists') {
res.sendStatus(200)
} else {
//res.sendStatus(error.statusCode).json(error)
res.sendStatus(500)
console.log(JSON.stringify(error))
}
})
})
I received the following response in the terminal:
{"status":404,"headers":{"access-control-expose-headers":"Date,
X-Envoy-Upstream-Service-Time, Server, Access-Control-Expose-Headers,
Access-Control-Max-Age","access-control-max-age":"86400",
"content-type":"application/json","date":"Thu, 09 Apr 2020 02:34:22
GMT","server":"istio-envoy",
"x-envoy-upstream-service-time":"11",
"content-length":"209","connection":"close"},
"error":"not_found","error_description":
"Not found","error_uri":"https://docs.pusher.com/errors/not_found"}
I do not know what any of this means.

Error method sendAll() in nodejs using firebase-admin

I use firebase-admin for nodejs(version 7.3.0) for sending push
notifications. For 40k distinct messages sending with method sendAll often server received this error:
"Credential implementation provided to initializeApp() via the "credential"
property failed to fetch a valid Google OAuth2 access token with the
following error: "Error fetching access token: Error while making request:
socket hang up. Error code: ECONNRESET".
Sometimes it works well but not all the time.
var admin = require('firebase-admin');
serviceAccount = require('/path_json_adminsdk/yyyyyyyyyy.json');
var defaultApp = admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://api-project-yyyyyy'
});
var k = 42000;
var contorMessages = 0;
var messages = [];
for(var i=0;i <em><</em> k; i++){
//.......
contorMessages = contorMessages + 1;
var tmp = {
alert: body.alert,
payload: body.payload
};
//form the array to be sent
messages.push({
data: {"body": JSON.stringify(tmp)},
token: body.token
});
if(contorMessages == 100){
SEDispatcher.emit('sendMessageFirebaseMulticast',messages);
contorMessages = 0;
messages = [];
}
}
SEDispatcher.on('sendMessageFirebaseMulticast', function(messages){
var dryRun = true;
admin.messaging().sendAll(messages, dryRun)
.then(function(response) {
//console.log("response:",response);
//responses = response.responses;
//.......
})
.catch((error) => {
console.log(' +++ Error sending message:', error);
});
});
the error that occurs sometimes:
+++ Error sending message: { Error: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a
valid Google OAuth2 access token with the following error: "Error
fetching access token: Error while making request: socket hang up.
Error code: ECONNRESET".
at FirebaseAppError.Error (native)
at FirebaseAppError.FirebaseError [as constructor] (/opt/node/test/node_modules/firebase-admin/lib/utils/error.js:42:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (/opt/node/test/node_modules/firebase-admin/lib/utils/error.js:88:28)
at new FirebaseAppError (/opt/node/test/node_modules/firebase-admin/lib/utils/error.js:122:28)
at /opt/node/test/node_modules/firebase-admin/lib/firebase-app.js:121:23
at process._tickCallback (internal/process/next_tick.js:103:7) errorInfo: { code: 'app/invalid-credential',
message: 'Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2
access token with the following error: "Error fetching access token:
Error while making request: socket hang up. Error code: ECONNRESET".'
}, codePrefix: 'app' }
const messaging = getMessaging(defaultApp);
Need to be load
let serviceAccount = require('./google.json');
function messaging() {
const defaultApp = initializeApp({
credential: admin.credential.cert(serviceAccount)
});
const messaging = getMessaging(defaultApp);
const topic = 'highScores';
const message = [
{
data: {
score: '850',
time: '2:45'
},
topic: topic
}
];
messaging
.sendAll(message, true)
.then(function (response) {
console.log('response:', response);
})
.catch((error) => {
console.log(' +++ Error sending message:', error);
});
}
Assuming that the JSON is the file that contains your private key that is generated when registering the project

Rate limiting request-promise in for loop

I'm trying to to limit the rate at which I'm firing GET requests to an outside API using promises but I'm having difficulty getting it working. In my scenario, I'm using 'request-promise' module and I need to send GET requests for 175 items from an API (one request for each item ID). The API has a rate limit of 40 requests per 10 seconds so my throttle needs to be 250ms per request. I am trying to send a request inside loop for each item ID, like:
files.forEach(function (file, i) {
console.log("The item ID is " + file.match(re)[1]);
client.send(new APIClient.requests.getItem(file.match(re)[1]))
.then((item) => {
...
})
.catch((error) => {
console.error(error);
// Use fallback
});
...
Here is a snippet of my API client return a request promise (rp) with a 250ms timeout and no callback:
const rp = require('request-promise');
const rp_errors = require('request-promise/errors');
...
send(request, callback) {
...
return rp(options)
.then(this._parseResponse)
.then((response)=> {
return new Promise( (resolve) => setTimeout(function(){
if (callback) { return callback(null, response); }
return resolve(response);
}, 250));
})
.catch(rp_errors.StatusCodeError,((error) => {
throw new errors.ResponseError(request, error.statusCode, error.message);
}
))
.catch(rp_errors.RequestError,((error) => {
if(error.cause.code === 'ETIMEDOUT' || error.cause.code === 'ESOCKETTIMEDOUT')
throw new errors.TimeoutError(request, error);
throw error;
}
))
.catch((error) => {
if (callback) {return callback(error)};
throw error;
});
}
The Async doesnt work and it returns this stack trace of "429 request limit exceeded"
{ ResponseError: 429 - {"status_code":25,"status_message":"Your request count (175) is over the allowed limit of 40."}
[0] at rp.then.then.catch (/mnt/c/Users/ridhwaan/Source/homehost/lib/api-client.js:52:19)
[0] at tryCatcher (/mnt/c/Users/ridhwaan/Source/homehost/node_modules/bluebird/js/release/util.js:16:23)
[0] at /mnt/c/Users/ridhwaan/Source/homehost/node_modules/bluebird/js/release/catch_filter.js:17:41
[0] at tryCatcher (/mnt/c/Users/ridhwaan/Source/homehost/node_modules/bluebird/js/release/util.js:16:23)
[0] at Promise._settlePromiseFromHandler (/mnt/c/Users/ridhwaan/Source/homehost/node_modules/bluebird/js/release/promise.js:512:31)
[0] at Promise._settlePromise (/mnt/c/Users/ridhwaan/Source/homehost/node_modules/bluebird/js/release/promise.js:569:18)
[0] at Promise._settlePromise0 (/mnt/c/Users/ridhwaan/Source/homehost/node_modules/bluebird/js/release/promise.js:614:10)
[0] at Promise._settlePromises (/mnt/c/Users/ridhwaan/Source/homehost/node_modules/bluebird/js/release/promise.js:689:18)
[0] at Async._drainQueue (/mnt/c/Users/ridhwaan/Source/homehost/node_modules/bluebird/js/release/async.js:133:16)
[0] at Async._drainQueues (/mnt/c/Users/ridhwaan/Source/homehost/node_modules/bluebird/js/release/async.js:143:10)
[0] at Immediate.Async.drainQueues [as _onImmediate] (/mnt/c/Users/ridhwaan/Source/homehost/node_modules/bluebird/js/release/async.js:17:14)
[0] at runCallback (timers.js:756:18)
[0] at tryOnImmediate (timers.js:717:5)
[0] at processImmediate [as _immediateCallback] (timers.js:697:5)
[0] name: 'ResponseError',
[0] request:
[0] Movie {
[0] method: 'GET',
[0] path: '/movie/24428',
[0] timeout: 10000,
[0] ensureHttps: false,
[0] external_id: '24428' },
[0] statusCode: 429 }
So the main issue is that array.forEach is a synchronous function and will not wait for client.send to finish.
A solution would be to use bluebird.mapSeries (http://bluebirdjs.com/docs/api/promise.mapseries.html) to map through an array and wait for each iteration to finish.
Also don't forget to return the send-promise, so the mapSeries-function will know when it has resolved, so it knows when to start the next iteration:
bluebird.mapSeries(files, function(file){
return send(...)
}
Last a suggestion would be to replace the whole .then(... setTimeout...) part with just .delay(250). Request-Promise already uses bluebird promises so you can make use of their convenience functions http://bluebirdjs.com/docs/api/delay.html. Delay will automatically resolve the value from the previous promise
return rp(options)
.then(this._parseResponse)
.delay(250)
.catch(...)

Resources