export async function signIn({ dispatch }, data) {
Loading.show()
firebaseAuth
.signInWithEmailAndPassword(data.email, data.password)
.then(async res => {
Loading.hide()
// if (!res.user.emailVerified) {
// dispatch('setNotification', {
// ...failed,
// message: 'Email not verified!'
// })
// return
// }
res.user.getIdToken().then(token => {
Loading.hide()
const { uid } = res.user
tempStorage.token = token
tempStorage.localId = uid
storage.delete(StorageKeys.token)
storage.set(StorageKeys.token, token)
storage.set(StorageKeys.localId, uid)
dispatch('setNotification', {
...success,
message: 'Successfully login!'
})
dispatch('getUserProfile')
// i need to access the value here from getUserProfile function
})
})
.catch(error => {
Loading.hide()
var msg = ''
switch (error.code) {
case 'auth/wrong-password':
msg = 'Wrong password'
break
case 'auth/user-not-found':
msg = 'User not found'
break
case 'auth/too-many-requests':
msg = 'Account temporarily suspended'
}
dispatch('setNotification', {
...failed,
message: msg
})
})
}
export async function getUserProfile({ dispatch, commit }) {
try {
const serviceUrl = `${urls.users}/${tempStorage.localId}`
const { data } = await request.get(serviceUrl)
commit('setUser', data)
} catch (err) {
console.log(err, 'err')
}
}
How do i access the value from this disptach(getUserProfile) function???
if (data.attributes.roles.includes('admin')) {
this.$router.push({ path: routesConfig.name.training })
} else {
this.$router.push({ path: routesConfig.name.profile })
}
i want this condition to run on basis of dispatch function
result and the upper condition will redirect me to different pages on basis of role
Thanks in advance!
Related
Following is my getUser function
const getUsers = async (req, res) => {
try {
ddb.get({
TableName: "Tablename",
Key: { Username: req.query.username }
},(err,user) => {
if(err || Object.keys(user).length === 0) {
return res.status(404).json("Something went wrong")
} else {
const userSociety = Object.keys(user.Item.Societies)[0]
ddb.get({
TableName: "Tablename",
Key: { SocietyCode: userSociety }
},(err, society) => {
if(err || Object.keys(society).length === 0) {
return res.status(400).json({ message: "Could not fetch society members" })
} else {
const users = Object.keys(society.Item.SocietyMembers)
const usersData = []
users.forEach(async u => {
ddb.get({
TableName: "TestMyMohallaUsers",
Key: { Username: u }
},async (err,user) => {
if(err || Object.keys(user).length === 0) {
} else usersData.push({
Username: user.Item.Username,
Firstname: user.Item.Name
})
})
})
return res.status(200).json({ message: "Data detched successfully", Users: usersData })
}
})
}
})
} catch (error) {
return res.status(500).json({ error: "Internal Server Error" })
}
}
I want to wait for the execution of forEach and then send back the data via return statement but as of now the return statement gives empty array of users.
Clearly my code in not waiting for the execution of forEach and then returning the data. How can I do that someone help me?
Edit: ddb is an instance of DynamoDB
You'll have a better time if you
use the DynamoDB Promise API instead of a pyramid of callbacks
refactor your code to a couple of functions
Finally, awaiting for all user fetches to complete requires Promise.all for all of those promises.
async function getUser(ddb, username) {
const user = await ddb
.get({
TableName: "TestMyMohallaUsers",
Key: { Username: username },
})
.promise();
if (!user.Item) {
throw new Error(`User ${username} not found`);
}
return user.Item;
}
async function getSociety(ddb, societyCode) {
const society = await ddb
.get({
TableName: "Tablename",
Key: { SocietyCode: societyCode },
})
.promise();
if (!society.Item) {
throw new Error(`Society ${societyCode} not found`);
}
return society.Item;
}
const getUsers = async (req, res) => {
try {
const user = await getUser(ddb, req.params.username);
const userSocietyCode = Object.keys(user.Societies)[0];
const society = await getSociety(ddb, userSocietyCode);
const societyUsers = Object.keys(society.SocietyMembers);
const usersData = await Promise.all(
societyUsers.map(async (member) => {
const user = await getUser(ddb, member);
return {
Username: user.Username,
Firstname: user.Name,
};
}),
);
return res
.status(200)
.json({
message: "Data detched successfully",
Users: usersData,
});
} catch (e) {
return res
.status(400)
.json({ message: `Could not fetch information: ${e}` });
}
};
How can I use the current status of redux after the thunks and actions have finished? The problem is in the handleSubmit function if I register a user with errors, it updates the status of redux with the message "Email already registered", but when accessing the state in the dispatch promise sends me a wrong state, without the message.
Function hanldeSubmit
const handleSubmit = (e) => {
e.preventDefault()
const form = {
name: e.target[0].value,
email: e.target[1].value,
password: e.target[2].value,
confirmPassword: e.target[3].value
}
const { name, email, password } = form
if (isFormValid(form)) {
//TODO: FIX IT synchronize redux with errors
dispatch( startRegisterUser(name, email, password) ).then(() => {
console.log(state)
})
}
}
register action and thunk
export const startRegisterUser = (name, email, password) => {
return (dispatch, state) => {
dispatch(startLoadingAction())
return firebase.auth().createUserWithEmailAndPassword(email, password)
.then(async ({ user }) => {
await user.updateProfile({
displayName: name,
photoURL: ''
})
dispatch(registerUserAction(user.uid, user.displayName))
})
.catch(e => {
if (e.code === "auth/email-already-in-use") {
dispatch(errorAction("Email already registered"))
} else {
dispatch(errorAction("Unexpected error"))
}
})
.then(() => {
dispatch(finishLoadingAction())
console.log("finished dispatch's", state())
return
})
}
}
export const registerUserAction = (uid, displayname) => {
return {
type: types.register,
payload: {
uid,
displayname
}
}
}
console logs
I want to get the status of the first console log but in the handlesubmit function
You should handle the errorAction in the reducer, update the ui store slice with the error message. And, you need to return the state() in the promise in the thunk function. Then, you will get the whole state inside the handleSubmit event handler.
E.g.
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
function errorAction(message) {
return {
type: 'ERROR',
payload: message,
error: true,
};
}
export const startRegisterUser = (name, email, password) => {
return (dispatch, state) => {
return Promise.reject({ code: 'auth/email-already-in-use' })
.catch((e) => {
if (e.code === 'auth/email-already-in-use') {
dispatch(errorAction('Email already registered'));
} else {
dispatch(errorAction('Unexpected error'));
}
})
.then(() => state());
};
};
export const registerUserAction = (uid, displayname) => {
return {
type: 'REGISTER',
payload: {
uid,
displayname,
},
};
};
function rootReducer(state = { ui: { error: '' } }, action) {
switch (action.type) {
case 'ERROR':
return { ui: { error: action.payload } };
default:
return state;
}
}
const store = createStore(rootReducer, applyMiddleware(thunk));
function handleSubmit() {
store
.dispatch(startRegisterUser('name', 'example#gmail.com', '123') as any)
.then((state) => {
console.log('handleSubmit state: ', state);
});
}
// triggered by user submit event
handleSubmit();
Output:
handleSubmit state: { ui: { error: 'Email already registered' } }
Below is my function returning login token when I debug my function it waits until return but when call function returns undefined and errors are also undefined don't know why it's happening
import userModel from '../Models/user.model';
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken')
let token = null;
process.env.SECRET_KEY = 'secret';
export default class loginController{
static async login(user:any): Promise<any>{
try{
await userModel.findOne({
Email: user.Email
})
.then(async (res:any) => {
if (user) {
if (await bcrypt.compareSync(user.Password, res.Password)) {
const payload = {
Firstname: res.Firstname,
Lastname: res.Lastname,
email: res.Email,
}
token = await jwt.sign(payload, process.env.SECRET_KEY, {
expiresIn: 1400
})
let decoded = jwt.verify(token, process.env.SECRET_KEY)
return token;
}
else {
return "Password is Wrong";
}
}
else {
return 'Please Check Username';
}
})
.catch(err => {
return('error : ' + err)
})
}
catch(err)
{
return err
}
}
}
And my calling function is
const router : Router = Router();
router.post('/login', async (req, res, next) => {
try {
const user = await loginController.login(req.body);
res.json(user)
} catch (error) {
res.json(error)
}
})
I tried call errors it's also debugger waiting until returns value to error but showing undefined
Thanks for the help!
login function doesn't return token because of function scoping. If you have multiple callbacks you can wrap it with a new Promise and use resolve function for returning values.
export default class loginController {
static async login(user: any): Promise<any> {
try {
return new Promise(async (resolve, reject) => {
await userModel
.findOne({
Email: user.Email
})
.then(async res => {
if (user) {
if (await bcrypt.compareSync(user.Password, res.Password)) {
const payload = {
Firstname: res.Firstname,
Lastname: res.Lastname,
email: res.Email
};
const token = await jwt.sign(payload, process.env.SECRET_KEY, {
expiresIn: 1400
});
let decoded = jwt.verify(token, process.env.SECRET_KEY);
resolve(token);
} else {
resolve('Password is Wrong');
}
} else {
resolve('Please Check Username');
}
})
.catch(err => {
resolve('error : ' + err);
});
});
} catch (error) {
return error;
}
}
}
I am unable to save username with AsyncStorage in my app.
I am using Switch component, if the value is true, username is saved and on logout the username should persist.
AsyncStorage returns undefined
// function for user to toggle if username should be saved
toggleRememberMe = value => {
this.setState({ rememberMe: value })
if (value === true) {
//user wants to be remembered.
this.rememberUser();
} else {
this.forgetUser();
}
}
// function to save username
rememberUser = async () => {
try {
await AsyncStorage.setItem('user_userID', this.state.signInEmail);
} catch (error) {
console.log(error)
}
};
// function to get username
getRememberedUser = async () => {
try {
const username = await AsyncStorage.getItem('user_userID');
if (username !== null) {
return username;
}
} catch (error) {
console.log(error)
}
};
// function to forget username or remove
forgetUser = async () => {
try {
await AsyncStorage.removeItem('user_userID');
} catch (error) {
console.log(error)
}
};
// componentDidMount
async componentDidMount() {
const username = await this.getRememberedUser();
console.log(username)
this.setState({
signInEmail: username || "",
rememberMe: username ? true : false });
}
//render
<Switch
trackColor={{true: '#16752A'}}
value={this.state.rememberMe}
onValueChange={(value) => this.toggleRememberMe(value)}
/>
<Text>Remember Me</Text>
How can I resolve this?
I am new to Node.js and I am struggling with Promises even after reading the tutorials provided by other stackflow users. I have already spent a whole evening on this and I am looking for help. I get the following error " Function returned undefined, expected Promise or value". My code is below. What am I doing wrong? I also have a suspicion that I have to use await/async because it looks like my code is running through without waiting for the first get to complete.
const admin = require('firebase-admin');
const functions = require('firebase-functions');
var db = admin.firestore();
exports.declinedRequest = functions.firestore
.document('requests/{requestId}')
.onUpdate((change, context) => {
const newValue = change.after.data();
const status = newValue.status;
const request = context.params.requestId;
var registrationToken;
var message;
if(status=="created") {
console.log('Checkpoint1 ',context.params.requestId);
newValue.friends.forEach(doc => {
console.log('Checkpoint 2: ', doc);
var usersRef = db.collection('users');
var query = usersRef.where('mobile', '==', doc).get()
.then(snapshotFriend => {
if (snapshotFriend.empty) {
console.log('Checkpoint3.');
return;
}
snapshotFriend.forEach(mobile => {
registrationToken = mobile.data().fcmToken;
console.log('FCM token =>', registrationToken);
if (!registrationToken) {
console.log('No fcmToken available');
return;
}
message = {
notification: {
body: "Request still available from " + newValue.requesterName,
sound: "default",
badge: 1
},
data: {
requestId: `${request}`
}
};
console.log('FCM token message created');
})
})
})
} else {
return;
}
return admin.messaging().sendToDevice(registrationToken, message)
.then(function (response) {
console.log("Successfully sent message:", response)
})
.catch(function (error) {
console.log("Error sending message:", error);
})
})
Try the code below hope this will work.
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const Promise = require('bluebird');
const _ = require('lodash');
let db = admin.firestore();
exports.declinedRequest = functions.firestore
.document('requests/{requestId}')
.onUpdate((change, context) => {
const newValue = change.after.data();
const status = newValue.status;
const request = context.params.requestId;
if (status == "created") {
console.log('Checkpoint1 ', context.params.requestId);
allPromises = [];
newValue.friends.forEach(doc => {
console.log('Checkpoint 2: ', doc);
const usersRef = db.collection('users');
// query for each document return promise.
allPromises.push(queryForEachDocument(doc,request,usersRef));
});
return Promise.all(allPromises);
} else {
return Promise.reject / resolve('Whatever you want.');
}
})
function queryForEachDocument(doc,request,usersRef) {
let promiseInvoices = []
let registrationToken;
let message;
return usersRef.where('mobile', '==', doc).get().then((snapshotFriend) => {
if (_.isEmpty(snapshotFriend)) {
console.log('Checkpoint3.');
return Promise.reject(new Error('Your error'));
}
snapshotFriend.forEach(mobile => {
registrationToken = mobile.data().fcmToken;
console.log('FCM token =>', registrationToken);
if (!registrationToken) {
console.log('No fcmToken available for', newValue.requesterName);
// Do anything you want to change here.
return Promise.reject(new Error('No fcmToken available for',newValue.requesterName));
}
message = {
notification: {
body: "Request still available from " + newValue.requesterName,
sound: "default",
badge: 1
},
data: {
requestId: request
}
};
console.log('FCM token message created');
// send invoice for each registrationToken
promiseInvoices.push(sendInvoice(registrationToken, message))
});
}).then(() => {
return Promise.all(promiseInvoices);
})
}
function sendInvoice(registrationToken, message) {
return admin.messaging().sendToDevice(registrationToken, message)
.then(function (response) {
console.log("Successfully sent message:", response)
})
.catch(function (error) {
console.log("Error sending message:", error);
})
}