Firebase verify tokenToken through Firebase-Admin Error - node.js

Hey I am trying to Verify User Token From Firebase Admin and then create a user based on that Information in Mongodb but Everytime when I request to this end point i got following error:
D:\React Course\Ecommerce\server\node_modules\firebase-admin\lib\auth\base-auth.js:421
if (properties?.providerToLink) {
^
SyntaxError: Invalid or unexpected token
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
Here is my code For Verification of userToken
const express=require("express");
import admin from "firebase-admin";
var serviceAccount = require("../FirebaseAdmin/Servicekey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
export const authcheck=async(req,res,next)=>{
try{
const firebaseuser=await admin.auth().verifyIdToken(req.headers.authcheck);
console.log(firebaseuser);
}catch(error){
console.log(error);
}
}
Can anyone Please Help me out on This I tried every possible way
Here is the Console.log of req.headers
And This is from Client side Where i am requesting to my end point
const createandupdateuser=async(authcheck)=>{
await axios.post("http://localhost:5000/api/create-and-update-user",{},{
headers:{
authcheck,
}
})
}
const handlesubmit=async(e)=>{
e.preventDefault();
try{
setloading(true);
const result=await signInWithEmailAndPassword(auth,email,password);
const {user}=result;
const Idtoken=await user.getIdTokenResult();
createandupdateuser(Idtoken.token);
dispatch({
type:"LOGGED_IN_USER",
payload:{
email:user.email,
token:Idtoken.token
}
})
navigate("/");
}catch(error){
console.log(error)
swal(error.message);
setloading(false);
}
}
Here is The authcheck function called
const express=require("express");
const router=express.Router();
import {createandupdateuser} from "../controllers/auth"
const {authcheck} =require("../middlewares/index");
router.post("/create-and-update-user",authcheck,createandupdateuser);
module.exports=router;

There is likely a hidden character among your code. Copy your code and paste it into a plain text editor and remove any junk text.
If you are using Visual Code you can turn on "Render whitespace".
Press CTRL + SHIFT + P / CMD + SHIFT + P and serach for "Render whitespace" and toggle it on

Update......I solved my Problem by Downgrading the Firebase-admin Version
npm i firebase-admin#10.3.0

Related

Setting up firebase Admin SDK in node

I am developing a password-recovery block for my application. I found out that I could call sendPasswordResetEmail function which works fine, but I want to use my own email template so I need to use Admin SDK and call admin.auth().generatePasswordResetLink(email) to generate a link where I could extract the OobCode to use resetPassword function. But for some reason I got the following error calling admin.auth().generatePasswordResetLink(email):
errorInfo: {
code: 'auth/insufficient-permission',
message: 'Credential implementation provided to initializeApp() via the "credential" property has insufficient permission to access the requested resource.
},
codePrefix: 'auth'
}
The permissions settting should be fine in firebase, altough I am totaly new in firebase.
Here is my code what includes the firebase-client initialization, admin sdk initialization, the post request:
import config from "config"
const serviceAccount = config.get('serviceAccount')
import admin from "firebase-admin";
const dbUrl = ""
try {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: dbUrl
});
} catch (e) {
console.log(e)
}
export {admin}
//------------------------------------------------
import { admin } from './firebase/firAdmin.js';
import {getAuth} from "firebase/auth";
import {initializeApp} from 'firebase/app';
const {
FIR_APP_ID,
FIR_API_KEY,
FIR_PROJECT_ID,
FIR_DATBASE_URL,
FIR_AUTH_DOMAIN,
FIR_STORAGE_BUCKET,
FIR_MESSAGING_SENDER_ID
} = process.env
const firConfig = {
appId: FIR_APP_ID,
apiKey: FIR_API_KEY,
authDomain: FIR_AUTH_DOMAIN,
databaseURL: FIR_DATBASE_URL,
projectId: FIR_PROJECT_ID,
storageBucket: FIR_STORAGE_BUCKET,
messagingSenderId: FIR_MESSAGING_SENDER_ID
}
const firApp = initializeApp(firConfig)
//------------------------------------------------
app.post('/password-recovery', async(req, res) => {
const {email} = req.body;
admin.auth().generatePasswordResetLink(email).then((link) => {
console.log(link)
})
.catch((err) => {
console.log(err)
});

I am getting this error: getFCMToken error ReferenceError: navigator is not defined when implementing push notification in nodeJs with firebase

I am getting this error while trying to implement push notification in nodeJs with firebase.
I have followed the documentation and am still getting this error. What could the problem be?
I will need help with this.
getFCMToken error ReferenceError: navigator is not defined
at /Users/decagon/Desktop/IGate System Projects/Errand Joe/Notification/node_modules/#firebase/messaging/src/api/getToken.ts:30:3
at step (/Users/decagon/Desktop/IGate System Projects/Errand Joe/Notification/node_modules/tslib/tslib.js:144:27)
at Object.next (/Users/decagon/Desktop/IGate System Projects/Errand Joe/Notification/node_modules/tslib/tslib.js:125:57)
at /Users/decagon/Desktop/IGate System Projects/Errand Joe/Notification/node_modules/tslib/tslib.js:118:75
at new Promise (<anonymous>)
at Object.__awaiter (/Users/decagon/Desktop/IGate System Projects/Errand Joe/Notification/node_modules/tslib/tslib.js:114:16)
at _getToken (/Users/decagon/Desktop/IGate System Projects/Errand Joe/Notification/node_modules/#firebase/messaging/dist/index.cjs.js:1147:18)
at /Users/decagon/Desktop/IGate System Projects/Errand Joe/Notification/node_modules/#firebase/messaging/src/api.ts:114:10
at step (/Users/decagon/Desktop/IGate System Projects/Errand Joe/Notification/node_modules/tslib/tslib.js:144:27)
at Object.next (/Users/decagon/Desktop/IGate System Projects/Errand Joe/Notification/node_modules/tslib/tslib.js:125:57)
I am trying to get a FCMToken to allow me send a push notification.
This is the code I have written but don't know what am doing wrong here.
import admin from "firebase-admin";
const { getMessaging, getToken } = require("firebase/messaging");
const serviceAccount = require("./src/serviceAccount.json");
const webPush = require('web-push');
// Generate a VAPID key pair
const vapidKeys = webPush.generateVAPIDKeys();
console.log('Public key:', vapidKeys.publicKey);
console.log('Private key:', vapidKeys.privateKey);
// Initialize the Firebase Admin SDK with the service account key file
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://notification-service-32997.nam5.firebaseio.com'
});
console.log("admin", admin);
// Define the notification payload
const payload = {
notification: {
title: "Hello, World!",
body: "This is a test push notification",
},
};
const messaging = admin.messaging();
(async function () {
try {
// Don't forget to paste your VAPID key here
// (you can find it in the Console too)
const token = await getToken({
vapidKey: vapidKeys.publicKey,
});
// const token = await messaging.tokenManager.getToken({
// vapidKey: process.env.PUBLIC_KEY,
// });
console.log("token", token)
return token;
} catch (e) {
console.log("getFCMToken error", e);
return undefined;
}
})();

I am trying to hash admin password to save into database using bcrypt in nextjs but receiving error

so everything is fine if I do not import bcrypt but once I do it I receive the following error in the terminal. I have searched a lot with no luck at this point I am clueless as what to do. any help would be greatly appreciated.
error - ./node_modules/#mapbox/node-pre-gyp/lib/clean.js:8:0
Module not found: Can't resolve 'fs'
Import trace for requested module:
./node_modules/#mapbox/node-pre-gyp/lib/ sync ^\.\/.*$
./node_modules/#mapbox/node-pre-gyp/lib/node-pre-gyp.js
./node_modules/bcrypt/bcrypt.js
./pages/adminlogin.js
https://nextjs.org/docs/messages/module-not-found
here is my adminlogin.js file
import bcrypt from "bcrypt";
export default function AdminLogin() {
const saltRounds = 10;
const createAdminData = async (e) => {
const usernameInfo = e.target.username.value;
console.log(usernameInfo);
const passwordInfo = e.target.password.value;
const salt = bcrypt.genSalt(saltRounds);
const hashedPassword = bcrypt.hash(passwordInfo, salt);
const res = await fetch("api/database/addadmindata", {
method: "POST",
headers: {
"Content-type": "application/json",
},
body: JSON.stringify({
username: usernameInfo,
password: hashedPassword,
}),
});
const result = await res.json();
router.reload();
};
That error happens because in client-side somewhere in your app you are using fs module. you can use fs module only on the server side, either getserverSideProps or apis directory.
When you import "fs" and use it in server-side, next.js will see that you use it in server-side so it won't add that import into the client bundle
probably that #mapbox is not a client library but you are using it in client-side
You probably have mongoose userSchema. in that schema file:
// hashing password before saving user
// for findAndUpdate(), pre save hook is not triggered
userSchema.pre("save", async function (next) {
// if password did not get changed, next()
if (!this.isModified("password")) {
next();
}
this.password = await bcrypt.hash(this.password, 10);
});
Now you do not need to do hashing on the server. you extract the data from req.body, you contract the user with the raw password, then run
await user.save()
so before "user" is saved, raw password will be hashed automatically and hashed password will be saved to the database

Node v 13 : Am I getting the 'type error: jwt.sign is not a function" because I'm using ES Modules?

Console Error: TypeError: jwt.sign is not a function
Trying out the latest Node version 13 using "type": "module" in my package.json. All is going well so far until I tried to add token authentication with 'jsonwebtoken'. Not sure if it's my code or maybe a compatibility issue? Using their ES Module has some differences from those I use in React.
create new token helper function
import * as jwt from 'jsonwebtoken'
export const newToken = user => {
return jwt.sign({id: user.id}, JWT_SECRET, {
expiresIn: '1d'
})
}
signup function
export const signup = async (req, res, next) => {
// ...
try {
//.. create user code ..
const user = new User({email, password})
user.save()
const token = newToken(user)
return res.json({token, user})
} catch (error) {
console.error(error)
res.status(500).send('Server Error')
}
and everytime I hit the signup route, I get the 500 Error, and a user still gets registered to my database. Hitting a wall a bit..
Thanks and happy holidays guys!
Edit: I just changed my import/export statements to common modules, and I was able to get tokens. Still don't know how to fix this to work with ESModules, or even what the issue is
jsonwebtoken uses default exports to expose its functions (https://github.com/auth0/node-jsonwebtoken/blob/master/index.js).
Therefore, you can load the module using import like this:
import jsonwebtoken from 'jsonwebtoken';
const token = jsonwebtoken.sign({ foo: 'bar' }, 'shhhhh');

Post Request Firebase Cloud Functions Timing Out

I know that each HTTP function must end with end() or send(), so I'm thinking that might be related to my issue. I'm building a Shopify app that I want to host on Firebase. I've gotten it to authenticate and install, but when I try to capture the permanent access token via POST, Firebase times out. This same code works fine with ngrok. Entire route function below.
const dotenv = require('dotenv').config();
const functions = require('firebase-functions');
const express = require('express');
const app = express();
const crypto = require('crypto');
const cookie = require('cookie');
const nonce = require('nonce')();
const querystring = require('querystring');
const request = require('request-promise');
const apiKey = process.env.SHOPIFY_API_KEY;
const apiSecret = process.env.SHOPIFY_API_SECRET;
const scopes = 'read_products,read_customers';
const forwardingAddress = 'https://my-custom-app.firebaseapp.com/app';
app.get('/app/shopify/callback', (req, res) => {
const { shop, hmac, code, state } = req.query;
const stateCookie = cookie.parse(req.headers.cookie).__session;
if (state !== stateCookie) {
return res.status(403).send('Request origin cannot be verified');
}
if (shop && hmac && code) {
// DONE: Validate request is from Shopify
const map = Object.assign({}, req.query);
delete map['signature'];
delete map['hmac'];
const message = querystring.stringify(map);
const generatedHash = crypto
.createHmac('sha256', apiSecret)
.update(message)
.digest('hex');
if (generatedHash !== hmac) {
return res.status(400).send('HMAC validation failed');
}
// Collect permanent access token
const accessTokenRequestUrl = 'https://' + shop + '/admin/oauth/access_token';
const accessTokenPayload = {
client_id: apiKey,
client_secret: apiSecret,
code,
};
// Everything works up until here
request.post(accessTokenRequestUrl, { json: accessTokenPayload })
.then((accessTokenResponse) => {
const accessToken = accessTokenResponse.access_token;
// If below is uncommented, it will not show on browser, Firebase seems to timeout on the above request.post.
//res.status(200).send("Got an access token, let's do something with it");
// Use access token to make API call to 'shop' endpoint
const shopRequestUrl = 'https://' + shop + '/admin/shop.json';
const shopRequestHeaders = {
'X-Shopify-Access-Token': accessToken,
};
request.get(shopRequestUrl, { headers: shopRequestHeaders })
.then((shopResponse) => {
res.end(shopResponse);
})
.catch((error) => {
res.status(error.statusCode).send(error.error.error_description);
});
})
.catch((error) => {
res.status(error.statusCode).send(error.error.error_description);
});
} else {
res.status(400).send('Required parameters missing');
}
});
exports.shopifyValidate = functions.https.onRequest(app);
You're calling response.end() incorrectly:
request.get(shopRequestUrl, { headers: shopRequestHeaders })
.then((shopResponse) => {
res.end(shopResponse);
})
As you can see from the linked documentation, end() doesn't take a parameter. It just ends the response. You probably want to be calling send() instead if you have data to send.
If you're unsure how your function is executing, also use console.log() to log messages to figure out exactly what it's doing. It's rarely a good idea to just hope that a bunch of code is just working - you should verify that it's working the way you expect.
Solved. Turns out you need a paid plan (Blaze, pay as you go) to access external APIs. I upgraded and that solved the issue.
What is the request module that you are using for the request.post()
Please see : https://www.npmjs.com/package/request#promises--asyncawait
I hope you are using the https://github.com/request/request-promise module instead of request.

Resources