I'm importing the following in my react app
const AWS = require('aws-sdk/dist/aws-sdk');
upon onSuccess in authenticateUser i'm getting the following error
onSignInFailure: TypeError: Cannot read properties of undefined (reading 'update')
at Object.onSuccess (authenticate.ts?c0c4:55:1)
at CognitoUser.authenticateUserInternal (CognitoUser.js?3c43:470:1)
at eval (CognitoUser.js?3c43:333:1)
at eval (CognitoUser.js?3c43:312:1)
at eval (Client.js?1610:140:1)
My code
import { CognitoUser, AuthenticationDetails } from "amazon-cognito-identity-js";
import Pool from "./UserPool";
const AWS = require('aws-sdk/dist/aws-sdk');
const authenticate = async (Username, Password) => (
await new Promise((resolve, reject) => {
const user = new CognitoUser({ Username, Pool });
const authDetails = new AuthenticationDetails({ Username, Password });
user.authenticateUser(authDetails, {
onSuccess: data => {
console.log('onSuccess:', data);
// AWS.config.region = 'us-east-1';
AWS.config.update({region: 'us-east-1'});
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', // your identity pool id here
Logins: {
// Change the key below according to the specific region your user pool is in.
'cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxxxxxx': data
.getIdToken()
.getJwtToken(),
},
});
console.log(AWS.config.credentials);
//refreshes credentials using AWS.CognitoIdentity.getCredentialsForIdentity()
AWS.config.credentials.refresh(error => {
if (error) {
console.error('refresh err: ',error);
} else {
// Instantiate aws sdk service objects now that the credentials have been updated.
// example: var s3 = new AWS.S3();
console.log('Successfully logged!');
}
});
resolve(data);
},
onFailure: err => {
console.error('onSignInFailure:', err);
reject(err);
}
});
})
)
Related
I have been following a tutorial on how to create my first Web3js application with solidity and react.
The tutorial was going great until I fall into this problem with metamask RPC.
The tutorial I have been following is this: https://www.youtube.com/watch?v=Wn_Kb3MR_cU&t=6333s&ab_channel=JavaScriptMastery
Right now I'm getting the following errors when trying to run function from ethereum:
inpage.js:1 MetaMask - RPC Error: The method "accounts " does not exist / is not available.
inpage.js:1 MetaMask - RPC Error: The method "eth_accounts " does not exist / is not available.
uncaught (in promise) {code: -32601, message: 'The method "eth_accounts " does not exist / is not available.', data: {…}, stack: '{\n "code": -32601,\n "message": "The method \\"eth…beogaeaoehlefnkodbefgpgknn/common-0.js:18:167275)'}
uncaught (in promise) {code: -32601, message: 'The method "eth_requestAccounts " does not exist / is not available.', data: {…}, stack: '{\n "code": -32601,\n "message": "The method \\"eth…beogaeaoehlefnkodbefgpgknn/common-0.js:18:167275)'}
The file that runs this is a context file TransactionContext.tsx:
import React, { useEffect, useState } from 'react';
import { ethers } from 'ethers';
import { contractABI, contractAddress } from '../utils/constants';
export const TransactionContext = React.createContext({} as any);
const { ethereum } = window as any;
const getEthereumContract = () => {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const transactionsContract = new ethers.Contract(contractAddress, contractABI, signer);
console.log({
provider,
signer,
transactionsContract
})
}
export const TransactionProvider = ({ children }: any) => {
const [currentAccount, setCurrentAccount] = useState('');
const checkIfWalletIsConnected = async () => {
if (!ethereum) return alert("Please install metamask!");
const accounts = await ethereum.request({ method: 'eth_accounts '});
console.log(accounts);
}
const connectWallet = async () => {
try {
if (!ethereum) return alert("Please install metamask!");
const accounts = await ethereum.request({ method: 'eth_requestAccounts '});
setCurrentAccount(accounts[0]);
} catch (e) {
console.log(e);
throw new Error('No Ethereum object.')
}
}
useEffect(() => {
checkIfWalletIsConnected();
}, [])
return (
<TransactionContext.Provider value={{ connectWallet }}>
{children}
</TransactionContext.Provider>
)
}
I see 3 issues in your contract:
1- you are not returning the contract from getEthereumContract. it should be
const getEthereumContract = () => {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const transactionsContract = new ethers.Contract(contractAddress, contractABI, signer);
return transactionsContract
}
I dont see you are using here yet but you might get bug in the future:
2- Error says 'The method "eth_accounts " does not exist ... you have extra space here "eth_accounts ". should be
const accounts = await ethereum.request({ method: 'eth_accounts'});
3- this is similar to second. You have extra space
const accounts = await ethereum.request({ method: 'eth_requestAccounts'});
You need to specify for which account you want to get the signer provider.getSigner(account)
On click of your connect button add this
async function connectWalletHandler() {
if (!ethereum) {
console.log("Make sure you have Metamask installed");
return;
} else {
console.log("Wallet exist");
}
const accounts = await ethereum.request({ method: "eth_requestAccounts" });
if (accounts.length !== 0) {
} else {
console.log("No authorized account found");
}
And put this code in you app.js
const [user,setUser]=useState(null);
Useeffect(()=>{
if (window.ethereum) {
const isMetaMaskConnected = async () => {
let provider = new ethers.providers.Web3Provider(window.ethereum);
const accounts = await provider.listAccounts();
let account = null;
if (accounts.length > 0) {
account = accounts[0];
}
let signer = provider.getSigner(account);
setUser({ provider: provider, signer: signer, account: account });
};
isMetaMaskConnected();
window.ethereum.on("chainChanged", (chainId) => {
window.location.reload();
});
window.ethereum.on("accountsChanged", () => {
window.location.reload();
});
} else {
}},[])
From now you have 3 option first user is null metamask not installed
2 user.account="" or null metamask installed and connected but locket
3 user.account have value this is when the wallet connected to the website and every thing 👍
I am using an aws-sdk in create-react-app to fetch dynamo DB data as a Guest user. In the Identity Pool, I have an unauthorized role that has limited access to a few tables that is public. When I tried to access data with the code below it shows Invalid credentials. I am new to aws, dynamo DB, I went through the documentation and tried out things. It's not worked as it is a bit different case.Please guide me the right approach to do this.
useEffect(() => {
AWS.config.update({
region: process.env.REACT_APP_REGION,
credentials: new AWS.CognitoIdentityCredentials({
IdentityPoolId: process.env.REACT_APP_USER_POOL_ID
})
});
const docClient = new AWS.DynamoDB.DocumentClient();
const params = {
TableName: "test_data",
Key:{ "id":"Test_2020_11_6_18"},
};
docClient.get(params, function(err, data) {
if (err) {
console.log(err);
} else {
console.log("Data"+ data)
}
});
}, [])
I will assume you have deployed the cognito federated identity and set
the role policy correctly.
I am used to with this approach to work with federated identity :
AWS.config.update({
region: process.env.REACT_APP_REGION
})
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
'IdentityPoolId': process.env.REACT_APP_USER_POOL_ID
});
const gp = AWS.config.credentials.getPromise();
gp.then(() => {
console.log(AWS.config.credentials.identityId)
const docClient = new AWS.DynamoDB.DocumentClient();
const params = {
TableName: "test_data",
Key: { "id": "Test_2020_11_6_18" },
};
docClient.get(params).promise().then(data => {
console.log("Data" + data)
}).catch(err => {
console.log(err);
})
}).catch((err) => {
console.log(err)
})
I am trying to send the validation email upon the account registration, using firebase. The registration is being done successfully but whenever I try to code email verification it gives me an error. Probably because I don't know where to place it. All my firebase methods are on Fire.js, which are the following:
import firebaseKeys from './Config';
import firebase from 'firebase';
require("firebase/firestore");
class Fire {
constructor() {
if (!firebase.apps.length) {
firebase.initializeApp(firebaseKeys);
}
}
addPost = async ({ text, localUri }) => {
const remoteUri = await this.uploadPhotoAsync(localUri, 'photos/${this.uid}/${Date.now()}');
return new Promise((res, rej) => {
this.firestore.collection('posts').add({
text,
uid: this.uid,
timestamp: this.timestamp,
image: remoteUri
})
.then(ref => {
res(ref);
})
.catch(error => {
rej(error);
});
});
}
uploadPhotoAsync = async (uri, filename) => {
return new Promise(async (res, rej) => {
const response = await fetch(uri);
const file = await response.blob();
let upload = firebase
.storage()
.ref(filename)
.put(file);
upload.on(
"state_changed",
snapshot => {},
err => {
rej(err);
},
async () => {
const url = await upload.snapshot.ref.getDownloadURL();
res(url);
}
);
});
}
createUser = async user => {
let remoteUri = null
try {
await firebase.auth().createUserWithEmailAndPassword(user.email, user.password)
//I tried to code it here with user.sendEmailVerification();
let db = this.firestore.collection("users").doc(this.uid)
db.set({
name: user.name,
email: user.email,
avatar: null
})
if (user.avatar) {
remoteUri = await this.uploadPhotoAsync(user.avatar, 'avatars/${this.uid}')
db.set({avatar: remoteUri}, {merge: true});
}
} catch (error) {
alert("Error: ", error);
}
};
get firestore() {
return firebase.firestore();
}
get uid() {
return (firebase.auth().currentUser || {}).uid;
}
get timestamp() {
return Date.now();
}
}
Fire.shared = new Fire();
export default Fire;
The createUserWithEmailAndPassword() method returns a Promise which resolves with a UserCredential AND (as the the doc indicates) "on successful creation of the user account, this user will also be signed in to your application."
So you can easily get the signed in user by using the user property of the UserCredential, and call the sendEmailVerification() method, as follows:
try {
const userCredential = await firebase.auth().createUserWithEmailAndPassword(user.email, user.password);
await userCredential.user.sendEmailVerification();
//In the next line, you should most probably use userCredential.user.uid as the ID of the Firestore document (instead of this.uid)
cont db = this.firestore.collection("users").doc(this.uid);
//...
} catch (...)
Note that you may pass an ActionCodeSettings object to the sendEmailVerification() method, see the doc.
I'm trying to create sign up form in react-native using Firebase.I've used Fetch Blob and Document Picker libraries for getting image and upload it to firebase. And I'm also trying to save the user's name, email, and password in realtime database. But unfortunately, the user data is not going to save in database except the image is uploaded in the firebase storage.
Here is my Firebase Auth Code
handleSignupOnPress = () => {
const {image, email, password} = this.state;
let validation = this.validateData();
console.warn(validation);
if (validation == true) {
this.toggleLoading();
firebaseService
.auth()
.createUserWithEmailAndPassword(email, password)
.then(() => {
// console.warn("User SignUp Successfully");
this.uploadImage(image);
})
.catch(error => {
this.toggleLoading();
var errorCode = error.code;
var errorMessage = error.message;
alert(errorMessage);
// console.warn("ERROR => ", errorCode, errorMessage);
});
}
};
Here is image Upload Code
// First Uploading image and download Image URI then call saveUserToDB()...
uploadImage(uri, mime = 'image/jpeg') {
return new Promise((resolve, reject) => {
const uploadUri =
Platform.OS === 'ios' ? uri.replace('file://', '') : uri;
let uploadBlob = '';
const imageRef = firebaseService
.storage()
.ref('images')
.child(uuid.v4());
fs.readFile(uploadUri, 'base64')
.then(data => {
return Blob.build(data, {type: `${mime};BASE64`});
})
.then(blob => {
uploadBlob = blob;
return imageRef.put(blob, {contentType: mime});
})
.then(() => {
uploadBlob.close();
const downnloadImageURI = imageRef.getDownloadURL().then(url => {
this.setState(
{
imageURI: url,
},
() => {
alert('ImageURI ==> ', this.state.imageURI);
this.saveUserInfo();
},
);
});
return downnloadImageURI;
})
.then(url => {
resolve(url);
})
.catch(error => {
this.toggleLoading();
reject(error);
});
});
}
Here is code for saving user's data
saveUserInfo = () => {
const {userName, email, password, imageURI} = this.state;
const {navigate} = this.props.navigation;
const uid = firebaseService.auth().currentUser.uid;
const params = {
image: imageURI,
username: userName,
email: email,
password: password,
};
//firebaseService.database().ref('/Users').push(params)
firebaseService
.database()
.ref('/Users')
.child(uid)
.set(params)
.then(res => {
this.toggleLoading();
navigate('Login');
})
.catch(err => {
alert(err);
});
};
Here are screenshots of Firebase Console
Are the "Rules" in database given permission to "Write"
Go to the firebase console and open your project.
Go to the database and search for "Rules" tab.
Check the rules are set as below
{
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
"rules": {
".read": true,
".write": true
}
}
I've solved this issue. The issue was in this piece of code.
const downnloadImageURI = imageRef.getDownloadURL().then(url => {
this.setState(
{
imageURI: url,
},
() => {
alert('ImageURI ==> ', this.state.imageURI);
this.saveUserInfo();
},
);
setState was not working and calback was not fired.
And I've made it like this way
const downnloadImageURI = imageRef.getDownloadURL().then(url => {
this.saveUserInfo(url)
);}
I'm using AWS Cognito Javascript SDK in a react application. I have a user that was created in the AWS Console by an admin, and when the user is logged in for the first time they have to reset their password. I go through the newPasswordRequired flow, and when I call the completeNewPasswordChallenge function with the parameters, the onFailure callback is ran. When I log the error I get, {code: "UnknownError", message: "Unknown error"}. However, when I check the AWS Console, the user in the user pool is changed from FORCE_CHANGE_PASSWORD to CONFIRMED.
My code is:
class LoginScreenContainer extends Component {
constructor(props) {
super(props);
this.state = {
isInvalidForm: null,
isFirstLogin: false,
user: null,
userAttr: null
}
this.onFormSubmission = this.onFormSubmission.bind(this);
this.updatePassword = this.updatePassword.bind(this);
}
onFormSubmission = (username, password) => {
const poolData = {
UserPoolId : AWSConfig.cognito.USER_POOL_ID,
ClientId : AWSConfig.cognito.APP_CLIENT_ID
}
const userPool = new CognitoUserPool(poolData);
const userData = {
Username: username,
Pool: userPool
}
const cognitoUser = new CognitoUser(userData);
const authenticationData = {
Username : username,
Password : password
}
const authenticationDetails = new AuthenticationDetails(authenticationData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
console.log(result);
},
onFailure: (err) => {
console.log("Authenticate user failure");
console.log(err);
this.setState({ isInvalidForm: true });
},
newPasswordRequired: (userAttributes) => {
delete userAttributes.email_verified;
delete userAttributes.phone_number_verified;
userAttributes.name = authenticationDetails.username;
console.log(userAttributes);
this.setState({
isFirstLogin: true,
user: cognitoUser,
userAttr: userAttributes
});
}
});
}
updatePassword = (newPassword) => {
const cognitoUser = this.state.user;
const userAttr = this.state.userAttr;
cognitoUser.completeNewPasswordChallenge(newPassword, userAttr, {
onSuccess: (result) => {
console.log("NEW PASSWORD COMPLETED: ");
console.log(result);
},
onFailure: (err) => {
console.log(err);
}
});
}
render() {
return (
<div>
{this.state.isFirstLogin ? (
<NewPasswordForm updatePassword={this.updatePassword} />
) : (
<LoginScreenComponent isInvalidForm={this.state.isInvalidForm} onFormSubmission={this.onFormSubmission}/>
)}
</div>
);
}
}
I believe you need to call completeNewPasswordChallenge within the newPasswordRequired callback.
newPasswordRequired: (userAttributes, requiredAttributes) => {
delete userAttributes.email_verified
cognitoUser.completeNewPasswordChallenge(newPw, userAttributes, {
onSuccess: result => {
AWS.config.credentials.refresh(err => {
if (err) {
throw err
} else {
// do something
}
})
},
newPasswordRequired: (userAttributes, requiredAttributes) => {
delete userAttributes.email_verified
// phone number as well
cognitoUser.completeNewPasswordChallenge(newPw, userAttributes, this.newPasswordRequired)
},
onFailure: err => {
throw err
}
})
},
I believe you have MFA on your account and you need to handle it from callback:
mfaSetup: (challengeName, challengeParameters) => { ... }
When you're handling mfaSetup form cognitoUser.authenticateUser() callback all is good if it's required, but from completeNewPasswordChallenge() callback there is no mfaSetup() in typings, which I believe AWS colleagues should fix it ASAP.
That's why you have empty error code, please check response tab in network dev tools on post req you made. I believe you'll find there MFA_SETUP challenge to solve.