Sha1 in Google API in React Native - reactjs

I'm a bit confused on generating SHA1 to access the Google cloud API. I have been developing an App which retrieve or display data after you login your google email, I've already used the clientID from the Google platform and paste it to my code but it doesn't work there's no error in my react mobile and I think the problem is the setup of my google API but I've already created one.
Most resources suggest to generate the `SHA1' by using the command below
keytool -list -v -keystore ./android/App/debug.keystore -alias androiddebugkey -storepass android -keypass android
Yet I see the result which generate the SHA1 but it's confusing me on how to used the generated SHA1 to google API
should I add SHA1 to google Platform console? how?
The comment/image below describes the solution to my project but I didn't understand at all
App.js
import React, { Component } from 'react';
import { View, StyleSheet, ToastAndroid, Button, Text, Image } from "react-native";
import {
GoogleSignin,
GoogleSigninButton,
statusCodes,
} from '#react-native-community/google-signin';
GoogleSignin.configure({
webClientId: '174................................9328.apps.googleusercontent.com', //sample
offlineAccess: true, // if you want to access Google API on behalf
});
class App extends Component {
constructor(props) {
super(props)
this.state = {
userGoogleInfo: {},
loaded: false
}}
signIn = async () => {
try {
console.log("asdsad");
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();
this.setState({
userGoogleInfo: userInfo,
loaded: true
})
console.log(this.state.userGoogleInfo);
console.log("ok");
} catch (error) {
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
console.log("e 1");
} else if (error.code === statusCodes.IN_PROGRESS) {
console.log("e 2");
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
console.log("e 3");
} else {
console.log(error.message);
console.log("errrorr");
}}
};
render() {
return (
<View>
<GoogleSigninButton
style={{ width: 222, height: 48 }}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Dark}
onPress={this.signIn}
/>
{this.state.loaded ?
<View>
<Text>{this.state.userGoogleInfo.user.name}</Text>
<Text>{this.state.userGoogleInfo.user.email}</Text>
<Image
style={{ width: 100, height: 100 }}
source={{ uri: this.state.userGoogleInfo.user.photo }}
/>
</View>
: <Text>Not SignedIn</Text>}
</View>
);}}
export default App;

Follow below steps for add SHA1 key in your google cloud console
you need to login your google cloud console when you create project https://console.cloud.google.com/apis/credentials?authuser=1&project=<your_project_id>
Then select your project and choose Credentials left bar menu
Right side API key section and click on API key which you want to
add SHA1 and add your SHA1 key which you generated from command
click on SAVE button below within dew minutes your app will work
Refer below attachment which show where you need to place SHA1 key in google cloud console project

Related

Using AWS clients at the global level in React?

A lot of the AWS API for Javascript relies on creating new AWS objects. For example, the S3 interface relies on creating an AWS object:
AWS.config.apiVersions = {
s3: '2006-03-01',
// other service API versions
};
var s3 = new AWS.S3();
It seems one needs to do this to send API requests to AWS services. However, I'm not sure how best to integrate this in React without creating new objects for every different kind of request; this seems very expensive. Is there a way of re-using the same AWS object for many different requests?
"I'm not sure how best to integrate this in React"
The best way to use the AWS SDK for JavaScript in a React app is to use version 3 and use Async Service Client calls. Your code is not version 3. The Service Client for V3 is S3Client.
Here is V3 JS code that uses Amazon S3 calls in a React app.
import React, { useState } from "javascriptv3/example_code/reactnative/App";
import { Button, StyleSheet, Text, TextInput, View } from "react-native";
import {
S3Client,
CreateBucketCommand,
DeleteBucketCommand,
} from "#aws-sdk/client-s3";
import { CognitoIdentityClient } from "#aws-sdk/client-cognito-identity";
import { fromCognitoIdentityPool } from "#aws-sdk/credential-provider-cognito-identity";
const App = () => {
const [bucketName, setBucketName] = useState("");
const [successMsg, setSuccessMsg] = useState("");
const [errorMsg, setErrorMsg] = useState("");
// Replace REGION with the appropriate AWS Region, such as 'us-east-1'.
const region = "REGION";
const client = new S3Client({
region,
credentials: fromCognitoIdentityPool({
client: new CognitoIdentityClient({ region }),
// Replace IDENTITY_POOL_ID with an appropriate Amazon Cognito Identity Pool ID for, such as 'us-east-1:xxxxxx-xxx-4103-9936-b52exxxxfd6'.
identityPoolId: "IDENTITY_POOL_ID",
}),
});
const createBucket = async () => {
setSuccessMsg("");
setErrorMsg("");
try {
await client.send(new CreateBucketCommand({ Bucket: bucketName }));
setSuccessMsg(`Bucket "${bucketName}" created.`);
} catch (e) {
setErrorMsg(e);
}
};
const deleteBucket = async () => {
setSuccessMsg("");
setErrorMsg("");
try {
await client.send(new DeleteBucketCommand({ Bucket: bucketName }));
setSuccessMsg(`Bucket "${bucketName}" deleted.`);
} catch (e) {
setErrorMsg(e);
}
};
return (
<View style={styles.container}>
<Text style={{ color: "green" }}>
{successMsg ? `Success: ${successMsg}` : ``}
</Text>
<Text style={{ color: "red" }}>
{errorMsg ? `Error: ${errorMsg}` : ``}
</Text>
<View>
<TextInput
style={styles.textInput}
onChangeText={(text) => setBucketName(text)}
autoCapitalize={"none"}
value={bucketName}
placeholder={"Enter Bucket Name"}
/>
<Button
backroundColor="#68a0cf"
title="Create Bucket"
onPress={createBucket}
/>
<Button
backroundColor="#68a0cf"
title="Delete Bucket"
onPress={deleteBucket}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
});
export default App;
To learn how to successfully setup the AWS SDK for JavaScript in a React app, see this doc topic:
Getting started in React Native

geolocation not working on google chrome in IRAN country in Chrome

In my React project, I am taking as inputs "Lat" and "Long" from user .I'm using geolocation to get user location. These changes are working fine with all browsers but not Chrome.
By using VPN and changing my IP, Chrome started working but this IP number is not real since my location changed.
Please help me to solve this issue or give me suggestion to try another package or Direction
thanks :)
import { useEffect } from "react";
export default function LocationInput({ Location, setLocation }) {
useEffect(() => {
if ("geolocation" in navigator) {
console.log("Available");
} else {
console.log("Not Available");
}
}, []);
const Handellocation = () => {
navigator.geolocation.getCurrentPosition(function (position) {
console.log(position.coords.latitude);
console.log(position.coords.longitude);
setLocation({
lat: position.coords.latitude,
long: position.coords.longitude,
ButtonText: "find you !",
ButtonColor: "#50C878",
});
});
};
return (
<div>
<p className="text">get locatin</p>
<div className="location">
<button
onClick={Handellocation}
style={{ backgroundColor: Location.ButtonColor }}
>
{Location.ButtonText}
</button>
</div>
</div>
);
}
I think this happens because of some countries being blacklisted for certain Google APIs, hence chrome wont support this. You need to work around with a different data-source ( DB/API/pollyfill)
Reference to the blacklisting: https://cloud.google.com/maps-platform/terms/maps-prohibited-territories

PDF File Uploaded to IPFS Does Not Display

Background
When running my app over localhost, I can choose my PDF file and submit it. I'm able to get the path of the IPFS file and display the path in the console.
Problem
When adding this line to display my file, it doesn't work and shows "No PDF file specified" instead.
<Document src={https://ipfs.infura.io/ipfs/${this.state.ipfshash}} />
<Document file={https://ipfs.infura.io/ipfs/${this.state.docupayHash}} />
What I've Tried
I've gone to the link in Google Chrome (ipfs.infura.io/ipfs/"QmUqB9dWDCeZ5nth9YKRJTQ6PcnfrGPPx1vzdyNWV6rh8s") and I can see the file there, so I know the link is correct.
Code
App.js
import React, { Component } from "react";
import { Document, Page } from 'react-pdf';
import web3 from "./web3";
import ipfs from "./ipfs";
import storehash from "./storehash";
import "./styles/App.css";
class App extends Component {
state = {
contractHash: null,
buffer: "",
ethAddress: "",
blockNumber: "",
transactionHash: ""
};
captureFile = (event) => {
event.stopPropagation()
event.preventDefault();
const file = event.target.files[0];
let reader = new window.FileReader();
reader.readAsArrayBuffer(file);
reader.onloadend = () => this.convertToBuffer(reader);
};
convertToBuffer = async (reader) => {
// Convert file to buffer so that it can be uploaded to IPFS
const buffer = await Buffer.from(reader.result);
this.setState({buffer});
};
onClick = async () => {
try {
await web3.eth.getTransactionReceipt(this.state.transactionHash, (err, txReceipt) => {
console.log(err, txReceipt);
this.setState({txReceipt});
});
} catch (error) {
console.log(error);
}
}
onSubmit = async (event) => {
event.preventDefault();
// Take the user's MetaMask address
const accounts = await web3.eth.getAccounts();
console.log("Sending from Metamask account: " + accounts[0]);
// Retrieve the contract address from storehash.js
const ethAddress= await storehash.options.address;
this.setState({ethAddress});
// Save document to IPFS, return its hash, and set it to state
await ipfs.add(this.state.buffer, (err, contractHash) => {
console.log(err, contractHash);
this.setState({ contractHash: contractHash[0].hash });
storehash.methods.setHash(this.state.contractHash).send({ from: accounts[0] }, (error, transactionHash) => {
console.log(transactionHash);
this.setState({transactionHash});
});
})
};
render() {
return (
<div className="app">
<h3> Choose file to send to IPFS </h3>
<form onSubmit={this.onSubmit}>
<input type="file" onChange={this.captureFile} />
<button type="submit">Submit</button>
</form>
<Document file={`https://ipfs.infura.io/ipfs/${this.state.contractHash}`} />
<a href={`https://ipfs.infura.io/ipfs/${this.state.contractHash}`}>Click to download the file</a>
<button onClick = {this.onClick}>Get Transaction Receipt</button>
<p>IPFS Hash: {this.state.contractHash}</p>
<p>Contract Address: {this.state.ethAddress}</p>
<p>Tx Hash: {this.state.transactionHash}</p>
</div>
);
}
}
export default App;
MyContract.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.16 <0.7.0;
contract MyContract {
string contractHash;
function setHash(string memory ipfsHash) public {
contractHash = ipfsHash;
}
function getHash() public view returns (string memory ipfsHash) {
return contractHash;
}
}
I've looked at other solutions on SO but none that I found were particularly related to my question. Thank you for your help and time!
Two things to try:
Add ?filename= parameter as a hint for both gateway and react-pdf:
<Document src={`https://ipfs.infura.io/ipfs/${this.state.ipfshash}?filename=test.pdf`} />
This will make content-type returned by the gateways more reliable and eliminate false-negatives in react-pdf.
Run your own gateway, or contact Infura and discuss raising request limits for your app.
FYI I've run below test multiple times:
$ curl -Ls 'https://dweb.link/ipfs/QmUqB9dWDCeZ5nth9YKRJTQ6PcnfrGPPx1vzdyNWV6rh8s?filename=test.pdf' > output && file output
output: PDF document, version 1.5
After a few times they stop returning PDF, instead they return HTML page with 429 Too Many Requests error:
output: HTML document, ASCII text, with CRLF line terminators
$ cat output
<html>
<head><title>429 Too Many Requests</title></head>
<body>
<center><h1>429 Too Many Requests</h1></center>
<hr><center>openresty</center>
</body>
</html>
It is very likely that react-pdf is unable to render your PDF because it gets 429 Too Many Requests error response instead of the PDF payload.

Electron in production mode pointing URL calls to file URL instead of proxy URL

I have created a simple application using React and Electron that handles few requests, the electron app works fine on dev mode, but during production, there is an issue, all the API calls, written in the code are pointing to file URL: /C:/... instead of proxy mapping to localhost.
Code Snippet is as:
export default class App extends Component {
state = { username: null };
componentDidMount() {
fetch('/api/getUsername')
.then(res => res.json())
.then(user => this.setState({ username: user.username }));
}
render() {
const { username } = this.state;
return (
<div>
<img src={ReactImage} alt="react" style={{ height: '250px' }} />
{username ? <h1>{`Hello there, I'm ${username}`}</h1> : <h1>Loading.. please wait!</h1>}
<Link to="/users">See More users</Link>
</div>
)
}
}
So I have no idea why this is happening, so it would of great help if anyone knows how to resolve it.
Thanks in advance!!

React Native - Set localStorage in WebView

I would like to set localStorage in the WebView component before loading the page.
https://facebook.github.io/react-native/docs/webview
My use case for this is that my RN app would like to open a page on it's accompanying website. The website authenticates on load by checking for a token in localStorage. If the token isn't there they will be prompted to login. Seen as the user has already logged in on the app I would prefer it if they could avoid logging in again in the WebView.
You might have overcome the issue. If not here is my solution.
You can use injectedJavaScript property of WebView and add javascript code to add the token on page load.
Example code snippet.
My Custom Javascript code that i need to inject.
let myInjectedJs = `(function(){ let tk = window.localStorage.getItem('tokenKey');
if(!tk || (tk && tk != '${token}')){
window.localStorage.setItem('tokenKey', '${token}');
window.location.reload();
}
})();`;
Code Explanation
Function is called as soon as loaded. Checks if tokenKey is already set. If not set we are setting it to the new token ${token} and reloading the page.
Note: We need to pass function as a string to injectedJavaScript in webview.
Using myInjectedJs in WebView.
<WebView
ref={webView => { this.refWeb = webView; }}
javaScriptEnabled={true}
injectedJavaScript={myInjectedJs}
...
Hope this solves your problem.
injectedJavaScript and window.ReactNativeWebView.postMessage should do the job.
import { WebView } from 'react-native-webview';
const INJECTED_JAVASCRIPT = `(function() {
const tokenLocalStorage = window.localStorage.getItem('token');
window.ReactNativeWebView.postMessage(tokenLocalStorage);
})();`;
export default function App() {
const onMessage = (payload) => {
console.log('payload', payload);
};
return (
<View style={styles.container}>
<StatusBar style="auto" />
<WebView
source={{ uri: 'https://somewebsite.com/login' }}
injectedJavaScript={INJECTED_JAVASCRIPT}
onMessage={onMessage}
/>
</View>
);
}
Payload data:
Object {
"nativeEvent": Object {
"canGoBack": true,
"canGoForward": false,
"data": "your_localstorage_value",
"loading": false,
"target": 3,
"title": "Coil",
"url": "https://somewebsite.com/home",
},
}
Works on both Android and iOS.

Resources