ipfs.cat returns "undefined" object in React-native - buffer

On React-native:
When I add a buffered string(i.e. Buffer(str) ) to IPFS using ipfs.add, the buffered string is added successfully and IPFS returns the hash.
When I try to retrieve the buffered string via ipfs.cat and the hash, ipfs.cat returns "undefined".
On Node.jS and ReactJs:
I do not have this problem. Both ipfs.add and ipfs.cat works.
Is the problem related to pinning in IPFS? or would changing the ipfs-api version in packag.json help?
Any help would be highly appreciated.
Below is the app.js code used for React-Native
import React, {useState, useRef} from 'react';
import {StyleSheet, Text, View, StatusBar, Button} from 'react-native';
const CryptoJS = require('crypto-js');
const ipfsAPI = require('ipfs-api');
// Connceting to the ipfs network via infura gateway
const ipfs = ipfsAPI('ipfs.infura.io', '5001', {protocol: 'https'});
export default function App() {
const [number, setNumber] = useState(0);
const [hash, setHash] = useState(' ');
console.log('printing: ', number);
//console.log('testing:', ipfs);
const handleCaseAdd = () => {
setNumber(1);
// Encrypt
const ciphertext = CryptoJS.AES.encrypt(
JSON.stringify('my message'),
'secret key 1234',
).toString();
console.log(' Ciphertext: ', ciphertext); // 'ciphertext
console.log('Buffered ciphertext: ', Buffer(ciphertext));
// Adding the encrpyted file to IPFS
ipfs.add(Buffer(ciphertext), {pin: true}, (error, result) => {
if (error) {
console.log(error);
return;
}
setHash(result[0].hash);
console.log('File added succesfully');
console.log('IPFS result: ', result);
});
}; // end of the function
const handleCaseGet = fileHash => {
//const fileHash = hash;
console.log('fileHash (before) :', fileHash);
ipfs.files.cat(fileHash, function(err, bufferedCiphertext) {
console.log('fileHash (after) :', fileHash);
console.log('Getting Buffered ciphertext: ', bufferedCiphertext);
});
}; // end of the function
//let confirmed;
//confirmed = true;
return (
<View style={styles.container}>
<View style={styles.first}>
<View style={styles.box1} />
<View style={styles.box2} />
</View>
<View>
<Button title="Add" onPress={handleCaseAdd} />
</View>
<Text> Number: {number} </Text>
<Text> Hash: {hash} </Text>
<View>
<Button title="Get" onPress={handleCaseGet.bind(this, hash)} />
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
//alignItems: "center",
//justifyContent: "center",
paddingTop: StatusBar.currentHeight,
},
first: {
backgroundColor: 'green',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-start',
},
box1: {
backgroundColor: 'dodgerblue',
width: 50,
height: 50,
//flex: 1,
},
box2: {
backgroundColor: 'gold',
width: 50,
height: 50,
//alignSelf: "flex-start",
},
});

ipfs-api has been deprecated for two years, the replacement is ipfs-http-client - could you please try with that module instead?
https://www.npmjs.com/package/ipfs-http-client

Related

in DropDownPicker onChangeValue is not triggering

I'm using DropDownPicker in react native but onChangeValue event is not triggering.
I have used onChange and onChangeItem already. Trying to follow this https://hossein-zare.github.io/react-native-dropdown-picker-website/docs/usage#onchangevalue but its not working. Please help me out.
Below is the code:
import React, { useEffect, useState } from 'react';
import {View, Text, Button, TextInput, FlatList, ActivityIndicator, StyleSheet, Image} from 'react-native';
import filter from 'lodash.filter';
import DropDownPicker from 'react-native-dropdown-picker';
const CarList = () => {
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState([]);
const [error, setError] = useState(null);
const [query, setQuery] = useState('');
const [fullData, setFullData] = useState([]);
const [selected, setSelected] = useState("");
const [open, setOpen] = useState(false);
const [childOpen, setChildOpen] = useState(false);
const [filterOption, setfilteroption] = useState([
{label: 'Color', value: 'Color'},
{label: 'Model', value: 'Model'},
{label: 'Year', value: 'Year'}
]);
const [value, setValue] = useState(null);
const [childvalue, setChildValue] = useState([]);
useEffect(() => {
setIsLoading(true);
fetch(`https://myfakeapi.com/api/cars/?seed=1&page=1&results=20`)
.then(response => response.json())
.then(response => {
setData(response.cars);
setFullData(response.cars);
setIsLoading(false);
})
.catch(err => {
setIsLoading(false);
setError(err);
});
}, []);
if (isLoading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" color="#5500dc" />
</View>
);
}
if (error) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontSize: 18}}>
Error fetching data... Check your network connection!
</Text>
</View>
);
}
const handleSearch = text => {
const formattedQuery = text.toLowerCase();
const filteredData = filter(fullData, user => {
return contains(user, formattedQuery);
});
setData(filteredData);
setQuery(text);
};
const contains = ({ car, car_model,car_color }, query) => {
if (car.toLowerCase().includes(query) || car_model.toLowerCase().includes(query) || car_color.toLowerCase().includes(query)) {
return true;
}
return false;
};
const color = [...new Set(data.map((item) => item.car_color))];
const model = [...new Set(data.map((item) => item.car_model))];
const year = [...new Set(data.map((item) => item.car_model_year))];
//this is not triggering
const changeSelectOptionHandler = (value) => {
console.log("hi")
setSelected(value);
};
if (selected === "Color") {
setChildValue(color)
} else if (selected === "Model") {
setChildValue(model)
} else if (selected === "Year") {
setChildValue(year)
}
function renderHeader() {
return (
<View
style={{
backgroundColor: '#fff',
padding: 10,
marginVertical: 10,
borderRadius: 20
}}
>
<TextInput
autoCapitalize="none"
autoCorrect={false}
clearButtonMode="always"
value={query}
onChangeText={queryText => handleSearch(queryText)}
placeholder="Search"
style={{ backgroundColor: '#fff', paddingHorizontal: 20 }}
/>
<DropDownPicker onChangeItem={changeSelectOptionHandler}
open={open}
value={value}
items={filterOption}
setOpen={setOpen}
setValue={setValue}
setItems={setfilteroption}
dropDownDirection="TOP"
style={{
padding: 5,
margin: 5,
width: 200,
flexDirection: 'row'
// borderRadius: 20
}}
/>
<DropDownPicker
open={childOpen}
items={childvalue}
setOpen={setChildOpen}
setItems={setChildValue}
dropDownDirection="TOP"
/>
</View>
);
}
return (
<View style={styles.container}>
<Text style={styles.text}>Favorite Contacts</Text>
<FlatList
keyboardShouldPersistTaps="always"
ListHeaderComponent={renderHeader}
data={data}
keyExtractor={({ id }) => id}
renderItem={({ item }) => (
<View style={styles.listItem}>
<Image
source={{
uri: 'https://picsum.photos/200',
}}
style={styles.coverImage}
/>
<View style={styles.metaInfo}>
<Text style={styles.title}>{`${item.car} ${
item.car_model
}`}</Text>
<Text>Color: {`${item.car_color}`}</Text>
<Text>Price: {`${item.price}`}</Text>
</View>
</View>
)}
/>
</View>
);
}
I needed to use onSelectItem instead of onChangeValue
The latest version of dropdownpicker
OnChangeValue is not supported.
use this :
onSelectItem={(item) => {console.log(item.value)}}
Note: I am using "react-native-dropdown-picker": "^5.4.2",

How to stop echo in iOS side react native audio-record-player?

Below my code for playing voice clip I send here from previous screen
import * as Progress from 'react-native-progress';
import { FontFamily, Fonts } from '../../common/GConstants';
import { Image, SafeAreaView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import React, { Component } from 'react';
import { heightPercentageToDP as hp, widthPercentageToDP as wp } from 'react-native-responsive-screen';
import AudioRecorderPlayer from 'react-native-audio-recorder-player';
import Colors from '../../common/GColors';
import GColors from '../../common/GColors';
import KeepAwake from 'react-native-keep-awake';
import WaveForm from 'react-native-audiowaveform';
import images from '../../assets/images/index';
import { secondsToTime } from '../../common/GFunction';
export default class ConfirmRecording extends Component {
constructor() {
super();
this.state = {
recordTime: '',
duration: '',
isPlaying: false,
totalDuration: '',
audioPath: '',
currentPositionSec: '',
currentDurationSec: '',
};
this.audioRecorderPlayer = new AudioRecorderPlayer();
}
showProgress = () => {
if (this.state.currentPositionSec / this.state.totalDuration > 1) {
return Math.round(
this.state.currentPositionSec / this.state.totalDuration,
);
} else {
return Math.fround(
this.state.currentPositionSec / this.state.totalDuration,
);
}
};
onStartPlay = async () => {
console.log('START and is playing', this.state.audioPath + "--------" + this.state.isPlaying);
if (this.state.isPlaying) {
this.setState({ isPlaying: false });
this.audioRecorderPlayer.stopPlayer();
this.audioRecorderPlayer.removePlayBackListener();
} else {
const msg = await this.audioRecorderPlayer.startPlayer(
this.state.audioPath,
// 'http://podcasts.cnn.net/cnn/services/podcasting/specials/audio/2007/05/milesobrien.mp3',
);
console.log('Play MSG', msg);
this.audioRecorderPlayer.addPlayBackListener((e) => {
this.setState({
isPlaying: true,
currentPositionSec: Math.round(
Math.round(Math.round(e.current_position / 10) / 100),
),
currentDurationSec: Math.round(Math.round(e.duration / 10) / 100),
playTime: e.current_position,
duration: e.duration,
});
if (e.duration == e.current_position) {
this.setState({ isPlaying: false });
console.log('Stopped');
this.audioRecorderPlayer.stopPlayer();
this.audioRecorderPlayer.removePlayBackListener();
}
return;
});
}
};
componentDidMount = () => {
var audioPath = this.props.navigation.getParam('audioPath');
var duration = this.props.navigation.getParam('duration');
console.warn("Data from prevciouyas screen", audioPath + "--------" + duration)
this.setState({
audioPath: audioPath,
duration: duration
});
}
componentWillUnmount = () => {
this.audioRecorderPlayer.stopPlayer();
this.audioRecorderPlayer.removePlayBackListener();
this.setState({
audioPath: '',
isPlaying: false
});
}
render() {
return (
<SafeAreaView style={style.mainContainer}>
<View style={style.audioView}>
<Text style={style.audioViewText}>Confirm Recording</Text>
<View style={{ marginTop: hp(2) }}>
<View style={style.secondWaveView}>
<WaveForm
style={style.WaveForm}
source={{ uri: this.state.audioPath }} // not work
stop={this.state.isPlaying}
play={this.state.isPlaying}
// autoPlay={true}
waveFormStyle={{ waveColor: Colors.gray, scrubColor: Colors.darkBlue }}
/>
<Text> {secondsToTime(this.state.currentPositionSec)
.m.toString()
.padStart(2, 0) +
':' +
secondsToTime(this.state.currentPositionSec)
.s.toString()
.padStart(2, 0)}</Text>
</View>
<View style={style.secondAudioView}>
<TouchableOpacity
onPress={(event) => {
this.audioRecorderPlayer.stopPlayer();
this.audioRecorderPlayer.removePlayBackListener();
this.setState({ audioPath: '', isPlaying: false }, () => {
// add Imerssion
// this.props.navigation.state.params.a(true),
this.props.navigation.navigate('ImpressionPro')
});
}
}
activeOpacity={.9}>
<Image source={images.sendIcon} />
</TouchableOpacity>
<View style={{ flex: 1 }} />
<TouchableOpacity style={style.icon}
onPress={() => {
this.audioRecorderPlayer.stopPlayer();
this.audioRecorderPlayer.removePlayBackListener();
this.setState({ audioPath: '', isPlaying: false }, () => {
this.props.navigation.pop(2)
});
}}
activeOpacity={.9}>
<Image source={images.deleteCancelBtn} />
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
this.onStartPlay()
.then(() => {
console.log('Playing');
})
.catch((err) => {
console.log('PErr', err);
});
}}
style={style.icon} activeOpacity={.9}>
<Image source={images.playBtn} />
</TouchableOpacity>
</View>
</View>
</View>
<KeepAwake />
</SafeAreaView>
)
}
}
const style = StyleSheet.create({
mainContainer:
{
flex: 1,
backgroundColor: Colors.darkBlue,
justifyContent: 'center',
alignItems: 'center'
},
secondWaveView:
{
marginTop: hp(2),
marginHorizontal: wp(5.5),
flexDirection: 'row',
justifyContent: 'space-between',
},
secondAudioView:
{
flexDirection: 'row',
marginTop: hp(2),
marginStart: wp(5)
},
WaveForm:
{
height: 25,
flex: 1,
},
icon:
{
marginEnd: wp(5)
},
audioView:
{
backgroundColor: Colors.white,
height: "25%",
width: "88%",
alignSelf: 'center',
borderRadius: hp(2),
},
audioViewText:
{
textAlign: 'center',
marginTop: hp(2),
fontSize: Fonts.fontsize20,
marginHorizontal: wp(6),
fontFamily: FontFamily.medium,
color: Colors.textCoffeeColor
},
})
issue was in the waveform for echo ... both were playing same time so thats why issue generated...

Google SignIn for IOS with React-native (expo)

I'm setting up a page where I can Id with a Google account. This is my code:
import React from "react"
import { StyleSheet, Text, View, Image, Button } from "react-native"
import * as Google from "expo-google-app-auth";
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
signedIn: false,
name: "",
photoUrl: ""
}
}
signIn = async () => {
try {
const result = await Google.logInAsync({
androidClientId:
"1051966217196.apps.googleusercontent.com",
iosClientId:
"1051966217196.apps.googleusercontent.com",
scopes: ["profile", "email"]
})
if (result.type === "success") {
this.setState({
signedIn: true,
name: result.user.name,
photoUrl: result.user.photoUrl
})
} else {
console.log("cancelled")
}
} catch (e) {
console.log("error", e)
}
}
render() {
return (
<View style={styles.container}>
{this.state.signedIn ? (
<LoggedInPage name={this.state.name} photoUrl={this.state.photoUrl} />
) : (
<LoginPage signIn={this.signIn} />
)}
</View>
)
}
}
const LoginPage = props => {
return (
<View>
<Text style={styles.header}>Sign In With Google</Text>
<Button title="Sign in with Google" onPress={() => props.signIn()} />
</View>
)
}
const LoggedInPage = props => {
return (
<View style={styles.container}>
<Text style={styles.header}>Welcome:{props.name}</Text>
<Image style={styles.image} source={{ uri: props.photoUrl }} />
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center"
},
header: {
fontSize: 25
},
image: {
marginTop: 15,
width: 150,
height: 150,
borderColor: "rgba(0,0,0,0.2)",
borderWidth: 3,
borderRadius: 150
}
})
On Android it's ok, everything is fine but in IOS I have that mistake :
Google 400 - That's an error - Error : redirect_uri_mismatch
Where is it goes wrong? I'm new to react native so I need detailed explanations.
I changed the bundle identifier to host.exp.exponent in Google credentials and it works. It's weird because I didn't change it in app.json. But it works.

React Native Camera: Access snapped image

I am using the react-native-camera plugin in my app. I am trying to take an image and then immediately upload it to an AWS S3 bucket via AWS Amplify.
My Code looks like this:
export default class Camera extends Component {
render() {
return (
<View style={styles.container}>
<RNCamera
ref={ref => {
this.camera = ref;
}}
style={styles.preview}
flashMode={RNCamera.Constants.FlashMode.auto}
permissionDialogTitle={'Permission to use camera'}
permissionDialogMessage={'We need your permission to use your phone\'s camera'}
/>
<TouchableOpacity
onPress={this.takePicture.bind(this)}
style={styles.capture}
>
<Text style={{fontSize: 15}}> SNAP </Text>
</TouchableOpacity>
</View>
);
}
takePicture = async function () {
if (this.camera) {
const options = {base64: true};
const data = await this.camera.takePictureAsync(options);
console.log(data.uri);
uploadPictureToS3(data.uri, "image.jpg");
}
};
}
function readFile(fileUri) {
return RNFetchBlob.fs.readFile(fileUri, 'base64').then(data => new Buffer(data, 'base64'));
}
function uploadPictureToS3(uri, key) {
readFile(uri).then(buffer => {
Storage.put(key, buffer, {
contentType: "image/jpeg"
})
})
.then(r => {
console.log(r);
})
.catch(e => {
console.error(e);
});
}
When trying to access the file using the readFile method I get the following error: Error: file not exists.
What is happening here? Why am I not able to read the image from the cache folder directly after it was taken?
Your code looks alright although there are some "weird" stuff.
You pass the option base64 to the takePictureAsync. This makes the camera return the base64 of picture taken automatically, but you do not use it for anything. You can do uploadPictureToS3(data.base64, "image.jpg"); And skip the readFile method.
Another thing is, don't know why it is like this, to get the image base64 from the uri we usually do:
const filepath = data.uri.split('//')[1];
const imageUriBase64 = await RNFS.readFile(filepath, 'base64');
So try the const filepath = data.uri.split('//')[1]; trick instead of passing data.uri directly.
i am using the RNCamera plugin in this app,this code show image tack by camera in app
import React, { Component } from 'react';
import { StyleSheet, Text, TouchableOpacity, View, Image } from 'react-native';
import { RNCamera } from 'react-native-camera';
export default class CameraPage extends Component {
constructor(props) {
super(props);
this.state = {
img : '',
}
}
takePicture = async function(camera) {
const options = { quality: 0.5, base64: true };
const data = await camera.takePictureAsync(options);
this.setState({
img: data.uri
})
};
render() {
const{img}= this.state;
return (
<View style={styles.container}>
<RNCamera
style={styles.preview}
type={RNCamera.Constants.Type.back}
flashMode={RNCamera.Constants.FlashMode.off}
permissionDialogTitle={'Permission to use camera'}
permissionDialogMessage={'We need your permission to use your camera phone'}
>
{({ camera}) => {
return (
<View style={{ flex: 0, flexDirection: 'row', justifyContent: 'center' }}>
<TouchableOpacity onPress={() => this.takePicture(camera)} style={styles.capture}>
<Text style={{ fontSize: 14 }}> SNAP </Text>
</TouchableOpacity>
</View>
);
}}
</RNCamera>
<View style={{flex:1,justifyContent: 'center', alignItems: 'center'}}>
<Image source={{uri:img}} style={{ width: 200, height: 200}}/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: 'black',
},
preview: {
flex: 2,
justifyContent: 'flex-end',
alignItems: 'center',
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
padding: 15,
paddingHorizontal: `**enter code here**`20,
alignSelf: 'center',
margin: 20,
},
});

React-Native/Expo Receiving ERROR 'null is not an object (evaluating 'match.localteam_name')

Here I am only running two API requests. The first one in the componentDidMount function works fine, but the second one labeled handleMatchFacts does not work. In short, Using React-Native I'm retrieving information from the API, mounting it to the page and then once the Touchablehighlight is clicked it is suppose to retrieve additional information from the API according to the 'id' that is passed in 'onPress'. I am able to console.log the json of the data in the second request, but for some reason when I setState with the new data and render it to the page in ListView, I get an error.
import React from 'react'
import { View, Text, StyleSheet, ListView, TouchableHighlight } from 'react-native'
export default class Main extends React.Component {
constructor() {
super();
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
matches: ds.cloneWithRows([]),
matchFacts: ds.cloneWithRows([])
};
this.handleShowMatchFacts.bind(this)
}
componentDidMount(){
fetch("http://api.football-api.com/2.0/matches?match_date=27.04.2017&to_date=27.04.2017&Authorization=565ec012251f932ea4000001fa542ae9d994470e73fdb314a8a56d76")
.then(res => res.json())
.then(matches => {
this.setState({
matches : this.state.matches.cloneWithRows(matches)
})
})
}
handleShowMatchFacts = id => {
console.log('match', id)
return fetch(`http://api.football-api.com/2.0/matches/${id}?Authorization=565ec012251f932ea4000001fa542ae9d994470e73fdb314a8a56d76`)
.then(res => res.json())
.then(matchFacts => {
console.log('match facts', matchFacts)
let selectedMatch = matchFacts;
this.setState({
matches : this.state.matches.cloneWithRows([]),
matchFacts : this.state.matchFacts.cloneWithRows(selectedMatch)
})
})
}
render() {
return (
<View style={styles.mainContainer}>
<Text
style={styles.header}>
Todays Matches</Text>
<ListView
style={styles.matches}
dataSource={this.state.matches}
renderRow={(matches) =>
<TouchableHighlight
onPress={() => this.handleShowMatchFacts(matches.id)}
underlayColor="green"
><Text style={styles.item}> {matches.localteam_name} {matches.localteam_score} - {matches.visitorteam_score} {matches.visitorteam_name} </Text>
</TouchableHighlight>
}
/>
<ListView
style={styles.matches}
dataSource={this.state.matchFacts}
renderRow={(match) =>
<Text style={styles.item}> {match.localteam_name} {match.localteam_score} - {match.visitorteam_score} {match.visitorteam_name} </Text>
}
/>
</View>
);
}
}
const styles = StyleSheet.create({
mainContainer : {
flex: 1,
padding: 20
},
header : {
textAlign: 'center'
},
matches : {
marginTop: 20
},
item : {
borderRadius: 4,
borderWidth: 0.5,
borderColor: 'green',
marginBottom: 5,
padding: 20,
textAlign: 'center',
},
});
You're probably seeing an issue because the second API request doesn't return an array, it returns an object. The cloneWithRows expects an array. Replacing this line
matchFacts : this.state.matchFacts.cloneWithRows(selectedMatch)
with
matchFacts : this.state.matchFacts.cloneWithRows([selectedMatch])
may help, depending on how you render this new data.
That's just a guess since I don't know what error you're receiving.

Resources