What im trying to do is to implement voice recognition to the project.
Im using expo.
To do that im using the https://github.com/react-native-voice/voice library.
I made research about this error but it seems nothing works.
When I have installed it it showed me this error:
Voice.js
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Image,
TouchableHighlight,
} from 'react-native';
import Voice, {
SpeechRecognizedEvent,
SpeechResultsEvent,
SpeechErrorEvent,
} from '#react-native-voice/voice';
type Props = {};
type State = {
recognized: string;
pitch: string;
error: string;
end: string;
started: string;
results: string[];
partialResults: string[];
};
class VoiceTest extends Component<Props, State> {
state = {
recognized: '',
pitch: '',
error: '',
end: '',
started: '',
results: [],
partialResults: [],
};
constructor(props: Props) {
super(props);
Voice.onSpeechStart = this.onSpeechStart;
Voice.onSpeechRecognized = this.onSpeechRecognized;
Voice.onSpeechEnd = this.onSpeechEnd;
Voice.onSpeechError = this.onSpeechError;
Voice.onSpeechResults = this.onSpeechResults;
Voice.onSpeechPartialResults = this.onSpeechPartialResults;
Voice.onSpeechVolumeChanged = this.onSpeechVolumeChanged;
}
componentWillUnmount() {
Voice.destroy().then(Voice.removeAllListeners);
}
onSpeechStart = (e: any) => {
console.log('onSpeechStart: ', e);
this.setState({
started: '√',
});
};
onSpeechRecognized = (e: SpeechRecognizedEvent) => {
console.log('onSpeechRecognized: ', e);
this.setState({
recognized: '√',
});
};
onSpeechEnd = (e: any) => {
console.log('onSpeechEnd: ', e);
this.setState({
end: '√',
});
};
onSpeechError = (e: SpeechErrorEvent) => {
console.log('onSpeechError: ', e);
this.setState({
error: JSON.stringify(e.error),
});
};
onSpeechResults = (e: SpeechResultsEvent) => {
console.log('onSpeechResults: ', e);
this.setState({
results: e.value,
});
};
onSpeechPartialResults = (e: SpeechResultsEvent) => {
console.log('onSpeechPartialResults: ', e);
this.setState({
partialResults: e.value,
});
};
onSpeechVolumeChanged = (e: any) => {
console.log('onSpeechVolumeChanged: ', e);
this.setState({
pitch: e.value,
});
};
_startRecognizing = async () => {
this.setState({
recognized: '',
pitch: '',
error: '',
started: '',
results: [],
partialResults: [],
end: '',
});
try {
await Voice.start('en-US');
} catch (e) {
console.error(e);
}
};
_stopRecognizing = async () => {
try {
await Voice.stop();
} catch (e) {
console.error(e);
}
};
_cancelRecognizing = async () => {
try {
await Voice.cancel();
} catch (e) {
console.error(e);
}
};
_destroyRecognizer = async () => {
try {
await Voice.destroy();
} catch (e) {
console.error(e);
}
this.setState({
recognized: '',
pitch: '',
error: '',
started: '',
results: [],
partialResults: [],
end: '',
});
};
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native Voice!</Text>
<Text style={styles.instructions}>
Press the button and start speaking.
</Text>
<Text style={styles.stat}>{`Started: ${this.state.started}`}</Text>
<Text style={styles.stat}>{`Recognized: ${
this.state.recognized
}`}</Text>
<Text style={styles.stat}>{`Pitch: ${this.state.pitch}`}</Text>
<Text style={styles.stat}>{`Error: ${this.state.error}`}</Text>
<Text style={styles.stat}>Results</Text>
{this.state.results.map((result, index) => {
return (
<Text key={`result-${index}`} style={styles.stat}>
{result}
</Text>
);
})}
<Text style={styles.stat}>Partial Results</Text>
{this.state.partialResults.map((result, index) => {
return (
<Text key={`partial-result-${index}`} style={styles.stat}>
{result}
</Text>
);
})}
<Text style={styles.stat}>{`End: ${this.state.end}`}</Text>
<TouchableHighlight onPress={this._startRecognizing}>
<Text>START</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this._stopRecognizing}>
<Text style={styles.action}>Stop Recognizing</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this._cancelRecognizing}>
<Text style={styles.action}>Cancel</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this._destroyRecognizer}>
<Text style={styles.action}>Destroy</Text>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
width: 50,
height: 50,
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
action: {
textAlign: 'center',
color: '#0000FF',
marginVertical: 5,
fontWeight: 'bold',
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
stat: {
textAlign: 'center',
color: '#B0171F',
marginBottom: 1,
},
});
export default VoiceTest;
app.json
{
"expo": {
"plugins": [
[
"#react-native-voice/voice",
{
"microphonePermission": "CUSTOM: Allow $(PRODUCT_NAME) to access the microphone",
"speechRecognitionPermission": "CUSTOM: Allow $(PRODUCT_NAME) to securely recognize user speech"
}
]
],
How can I solve this?
Related
I am building a react-native app on windows and testing it on physical android device. The basic purpose of the app is to convert speech into text. I am using #react-native-voice library. First I created the app with
npx react-native init myapp
But on pressing the record button, it gives an error/warning of
cannot read properties of undefined( reading 'startSpeech)
Similarly I got the same warning for stopSpeech, destroySpeech etc.
After hectic search, I moved to expo-cli for creating the react-native app. But facing the same error again. Expo community expert says that expo has added the #react-native-voice into its expo-SDK > 41. You just have to add the plugins section into your app.json. plugin thing is explained in this stackOverflow post
I have tried everything but nothing is working.
The code is attached below
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Image,
TouchableHighlight,
} from 'react-native';
import Voice, {
SpeechRecognizedEvent,
SpeechResultsEvent,
SpeechErrorEvent,
} from '#react-native-voice/voice';
type Props = {};
type State = {
recognized: string;
pitch: string;
error: string;
end: string;
started: string;
results: string[];
partialResults: string[];
};
class App extends Component<Props, State> {
state = {
recognized: '',
pitch: '',
error: '',
end: '',
started: '',
results: [],
partialResults: [],
};
constructor(props: Props) {
super(props);
Voice.onSpeechStart = this.onSpeechStart.bind(this);
Voice.onSpeechRecognized = this.onSpeechRecognized;
Voice.onSpeechEnd = this.onSpeechEnd;
Voice.onSpeechError = this.onSpeechError;
Voice.onSpeechResults = this.onSpeechResults;
Voice.onSpeechPartialResults = this.onSpeechPartialResults;
Voice.onSpeechVolumeChanged = this.onSpeechVolumeChanged;
}
componentWillUnmount() {
Voice.destroy().then(Voice.removeAllListeners);
}
onSpeechStart = (e: any) => {
console.log('onSpeechStart: ', e);
this.setState({
started: '√',
});
};
onSpeechRecognized = (e: SpeechRecognizedEvent) => {
console.log('onSpeechRecognized: ', e);
this.setState({
recognized: '√',
});
};
onSpeechEnd = (e: any) => {
console.log('onSpeechEnd: ', e);
this.setState({
end: '√',
});
};
onSpeechError = (e: SpeechErrorEvent) => {
console.log('onSpeechError: ', e);
this.setState({
error: JSON.stringify(e.error),
});
};
onSpeechResults = (e: SpeechResultsEvent) => {
console.log('onSpeechResults: ', e);
this.setState({
results: e.value,
});
};
onSpeechPartialResults = (e: SpeechResultsEvent) => {
console.log('onSpeechPartialResults: ', e);
this.setState({
partialResults: e.value,
});
};
onSpeechVolumeChanged = (e: any) => {
console.log('onSpeechVolumeChanged: ', e);
this.setState({
pitch: e.value,
});
};
_startRecognizing = async () => {
this.setState({
recognized: '',
pitch: '',
error: '',
started: '',
results: [],
partialResults: [],
end: '',
});
try {
await Voice.start('en-US');
} catch (e) {
console.error(e);
}
};
_stopRecognizing = async () => {
try {
await Voice.stop();
} catch (e) {
console.error(e);
}
};
_cancelRecognizing = async () => {
try {
await Voice.cancel();
} catch (e) {
console.error(e);
}
};
_destroyRecognizer = async () => {
try {
await Voice.destroy();
} catch (e) {
console.error(e);
}
this.setState({
recognized: '',
pitch: '',
error: '',
started: '',
results: [],
partialResults: [],
end: '',
});
};
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native Voice!</Text>
<Text style={styles.instructions}>
Press the button and start speaking.
</Text>
<Text style={styles.stat}>{`Started: ${this.state.started}`}</Text>
<Text style={styles.stat}>{`Recognized: ${
this.state.recognized
}`}</Text>
<Text style={styles.stat}>{`Pitch: ${this.state.pitch}`}</Text>
<Text style={styles.stat}>{`Error: ${this.state.error}`}</Text>
<Text style={styles.stat}>Results</Text>
{this.state.results.map((result, index) => {
return (
<Text key={`result-${index}`} style={styles.stat}>
{result}
</Text>
);
})}
<Text style={styles.stat}>Partial Results</Text>
{this.state.partialResults.map((result, index) => {
return (
<Text key={`partial-result-${index}`} style={styles.stat}>
{result}
</Text>
);
})}
<Text style={styles.stat}>{`End: ${this.state.end}`}</Text>
<TouchableHighlight onPress={this._startRecognizing}>
<Image style={styles.button} source={require('./button.png')} />
</TouchableHighlight>
<TouchableHighlight onPress={this._stopRecognizing}>
<Text style={styles.action}>Stop Recognizing</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this._cancelRecognizing}>
<Text style={styles.action}>Cancel</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this._destroyRecognizer}>
<Text style={styles.action}>Destroy</Text>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
width: 50,
height: 50,
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
action: {
textAlign: 'center',
color: '#0000FF',
marginVertical: 5,
fontWeight: 'bold',
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
stat: {
textAlign: 'center',
color: '#B0171F',
marginBottom: 1,
},
});
export default App;
Thank you in advance for the help :)
I am creating an app which uses the phone's location. I would like to be able to get the latitude and longitude and using it as part of an api address.
I have been following this sample code using react-native-get-location and have been able to print the information in json formate but can't pull the latitude and longitude and use them.
react-native-get-location
Here is my code.
import GetLocation from 'react-native-get-location'
export default class App extends React.Component {
constructor (props) {
super(props);
this.state = {
isLoading: true,
latitude: null,
longitude: null,
location: null
};
}
_requestLocation = () => {
GetLocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 150000,
})
.then(location => {
this.setState ({
location,
isLoading: false,
});
})
.catch(error => {
const { code, message} = error;
if (code === 'CANCELLED') {
Alert.alert('location cancelled by user or by another request');
}
if (code === 'UNAVAILABLE') {
Alert.alert('Location service is disabled or unavailable');
}
if (code === 'TIMEOUT') {
Alert.alert('Location request timed out');
}
if (code === 'UNAUTHORIZED') {
Alert.alert('Authorization denied')
}
this.setState({
location: null,
isLoading: false,
});
});
}
componentDidMount() {
GetLocation.getCurrentPosition(async (info) => {
const location = await GetLocation(
info.coords.latitude,
info.coords.longitude
);
})
const fetch = require('node-fetch');
fetch('https://api.weatherapi.com/v1/forecast.json?&q=London', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
}).then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
this.setState({
isLoading: false,
dataSource: responseJson,
})
}).catch((error) => {
console.error(error);
});
}
render() {
const {location, isLoading} = this.state;
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={{flex:1, paddingTop: 20}}>
<Text>{JSON.stringify(location, 0, 2)}</Text>
<View style={{flex:1, flexDirection: 'row', textAlign: 'center', paddingLeft: 90}}>
<Button
disabled={isLoading}
title="Get Location"
onPress={this._requestLocation}
/>
</View>
</View>
)
}
}
Use expo-location instead of react-native-get-location as it is very easy to implement.
Here is the working app: Expo Snack
Screenshot:
import React, { useEffect, useState } from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
let apiKey = 'YOUR_API_KEY';
import * as Location from 'expo-location';
export default function App() {
const [location, setLocation] = useState(null);
const [errorMsg, setErrorMsg] = useState(null);
const [address, setAddress] = useState(null);
// const [getLocation, setGetLocation] = useState(false);
const getLocation = () => {
(async () => {
let { status } = await Location.requestPermissionsAsync();
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
}
Location.setGoogleApiKey(apiKey);
console.log(status);
let { coords } = await Location.getCurrentPositionAsync();
setLocation(coords);
console.log(coords);
if (coords) {
let { longitude, latitude } = coords;
let regionName = await Location.reverseGeocodeAsync({
longitude,
latitude,
});
setAddress(regionName[0]);
console.log(regionName, 'nothing');
}
// console.log();
})();
};
return (
<View style={styles.container}>
<Text style={styles.big}>
{!location
? 'Waiting'
: `Lat: ${location.latitude} \nLong: ${
location.longitude
} \n${JSON.stringify(address?.['subregion'])}`}
</Text>
<TouchableOpacity onPress={getLocation}>
<View
style={{
height: 100,
backgroundColor: 'teal',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
marginTop: 20,
}}>
<Text style={styles.btnText}> GET LOCATION </Text>
</View>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
alignItems: 'center',
justifyContent: 'center',
},
big: {
fontSize: 18,
color: 'black',
fontWeight: 'bold',
},
btnText: {
fontWeight: 'bold',
fontSize: 25,
color: 'white',
},
});
react-native-geolocation-service is a good alternative too for fetching latitude & longitude values.
Example usage:
import GeoLocation from 'react-native-geolocation-service';
const getDeviceCurrentLocation = async () => {
return new Promise((resolve, reject) =>
GeoLocation.getCurrentPosition(
(position) => {
resolve(position);
},
(error) => {
reject(error);
},
{
enableHighAccuracy: true, // Whether to use high accuracy mode or not
timeout: 15000, // Request timeout
maximumAge: 10000 // How long previous location will be cached
}
)
);
};
Trying to apply a default query in the reactive search component and it doesn't have an effect
import React from 'react';
import {
NavigationScreenProps,
NavigationScreenConfig, NavigationActions,
} from 'react-navigation';
import {
ChatHeader,
ChatHeaderNavigationStateParams,
} from '#src/components/messaging';
import {
Conversation,
} from '#src/core/model';
import {conversation5} from '#src/core/data/conversation';
import {StyleSheet, Text, Image, TouchableWithoutFeedback} from 'react-native';
import {
ReactiveBase,
DataSearch,
ReactiveList,
} from '#appbaseio/reactivesearch-native';
import {ScrollView, View} from 'react-native';
import {Icon, ListItem} from '#kitten/ui';
import LottieView from 'lottie-react-native';
import {SearchHeader} from '#src/components/search/search.header';
import {userProvider} from '../../../../domain/auth/UserProvider';
import {Screen} from '../../../../core/navigation/screens';
import Tts from 'react-native-tts';
import {StarIconOutline} from '#src/assets/icons';
import axios, {AxiosError, AxiosResponse} from 'axios';
import {Config} from '../../../../constants/Config';
import {User} from '#domain/models';
import DoubleClick from 'react-native-double-tap';
import {Notification} from 'react-native-in-app-message';
import AnimatedLoader from 'react-native-animated-loader';
interface State {
newMessageText: string;
conversation: Conversation;
isLoading: boolean;
message: string;
}
const styles = StyleSheet.create({
container: {
padding: 10,
marginTop: 25,
},
image: {
width: 100,
height: 100,
},
result: {
flexDirection: 'row',
width: '100%',
margin: 5,
alignItems: 'center',
},
notification: {
flexDirection: 'row',
width: '100%',
margin: 5,
padding: 5,
alignItems: 'flex-start',
},
item: {
flexDirection: 'column',
paddingLeft: 10,
},
title: {
fontWeight: 'bold',
},
lottie: {
width: 100,
height: 100,
},
iconx: {
width: 50,
height: 40,
marginLeft: -3,
marginBottom: -10,
padding: 5,
},
notificationText: {
marginTop: 11,
},
});
export class SearchContainer extends React.Component<NavigationScreenProps, State> {
private notification: Notification;
private token: string;
public state: State = {
newMessageText: '',
conversation: conversation5,
isLoading: false,
message: '',
};
private infiniteAnimationIconRef: React.RefObject<Icon> = React.createRef();
static navigationOptions: NavigationScreenConfig<any> = ({navigation, screenProps}) => {
const headerProps: ChatHeaderNavigationStateParams = {
interlocutor: navigation.getParam('interlocutor', conversation5.interlocutor),
lastSeen: navigation.getParam('lastSeen', 'today'),
onBack: navigation.getParam('onBack'),
onProfile: navigation.getParam('onProfile'),
};
const header = (navigationProps: NavigationScreenProps) => {
return (
<SearchHeader
{...navigationProps}
{...headerProps}
/>
);
};
return {...navigation, ...screenProps, header};
};
public async componentWillMount(): void {
this.props.navigation.setParams({
onBack: this.onBackPress,
});
await userProvider.get().then((data) => {
this.token = data.token;
}).catch(() => {
this.props.navigation.navigate(Screen.Login);
});
}
public componentDidMount() {
this.setState({
isLoading: false,
});
}
private onBackPress = (): void => {
this.props.navigation.goBack(null);
};
private say(deText): void {
Tts.setDefaultLanguage('de-DE');
Tts.setDucking(true);
Tts.speak(deText);
}
private star(id): void {
this.setState({isLoading: true});
axios.post(Config.service.stars.url, {
sentence_id: id,
}, {
headers: {
'Authorization': `Bearer ${this.token}`,
},
}).then((response: AxiosResponse<UserData>) => {
this.setState({message: 'Star added!'});
setTimeout(() => this.notification.show(), 100);
this.setState({isLoading: false});
}).catch((error: AxiosError) => {
let errorMessage = null;
try {
const code = error.response.request.status;
if (code === 401) {
this.props.navigation.navigate(Screen.Login);
} else if (code === 422) {
errorMessage = 'Star was added already for this sentence!';
} else {
errorMessage = 'Service is unavailable, please try again in a few!';
}
} catch (e) {
errorMessage = 'Service is unavailable, please try again in a few!';
}
this.setState({...this.state, message: errorMessage});
setTimeout(() => this.notification.show(), 100);
this.setState({isLoading: false});
});
}
public render(): React.ReactNode {
return (
<ReactiveBase
app='myapp'
url='http://xxx.xxxxxx.io'
headers={{'X-Api-Key': 'xxxxxxxxxxxxxxxxxxxxxxxxx'}}>
<View>
<DataSearch
componentId='searchbox'
dataField={[
'sentence',
'sentence.en',
'sentence.de',
'raw.translated',
]}
value='1'
highlight={true}
placeholder='words or expressions'
defaultQuery={() => ({
query: {
match: {
message: {
query: 'test',
},
},
},
})}
autosuggest={false}
/>
</View>
<Notification
customComponent={(
<View style={styles.notification}>
<LottieView
style={styles.iconx}
source={require('#src/animations/warning.json')}
colorFilters={[{
keypath: 'button',
color: '#F00000',
}, {
keypath: 'Sending Loader',
color: '#F00000',
}]}
autoPlay
loop={true}
/>
<Text style={styles.notificationText}>{this.state.message}</Text>
</View>
)}
ref={(c) => this.notification = c}
/>
<AnimatedLoader
visible={this.state.isLoading}
overlayColor='rgba(255,255,255,0.75)'
source={require('#src/animations/loader.json')}
animationStyle={styles.lottie}
speed={1}
/>
<ScrollView
stickyHeaderIndices={[1]}
nativeID={'scoller'}
>
<View>
<ReactiveList
componentId='results'
dataField='sentence.de'
size={7}
showResultStats={false}
pagination={true}
infiniteScroll={true}
scrollTarget={'scroller'}
react={{
and: 'searchbox',
}}
defaultValue={'Harry Potter'}
onData={(res, idx) => (
<View style={styles.result} key={res._id}>
<DoubleClick
singleTap={() => {
this.star(res._id);
}}
doubleTap={() => {
}}
delay={1000}
>
<Icon name='star-outline' fill='#FF9999' width='30' height='50'/>
</DoubleClick>
<ListItem
onPress={() => this.say(res.sentence.de)}
title={res.sentence.de}
description={res.raw.translated}
/>
</View>
)}
/>
</View>
</ScrollView>
</ReactiveBase>
);
}
}
<DataSearch
componentId='searchbox'
dataField={[
'sentence',
'sentence.en',
'sentence.de',
'raw.translated',
]}
value='1'
highlight={true}
placeholder='words or expressions'
defaultQuery={() => ({
query: {
match: {
message: {
query: 'test',
},
},
},
})}
autosuggest={false}
/>
Try this (i.e. use filter instead of should):
<ReactiveComponent
componentId='filterbox'
customQuery={props => ({
query: {
'bool': {
'filter': [{
'ids': {
'type': 'mydoctype',
'values': ['TK6IRm4BK9UoLvJay0OC', 'Ra6IRm4BK9UoLvJaykMD'],
},
}]
},
}
})}
/>
This may sound duplicated, but it's not.
I'm kinda newbie in React-Native.
I'm trying to write an MQTT-Client app, making use of "react-native-paho-mqtt" library, which should be able to connect to my own broker with this uri: tcp://217.218.171.92:1883
but apparently the uri must be started with "wss" only!!!
How can I make my app use tcp:// ?
above that, is it possible??
here is my App.js:
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
TouchableHighlight,
TextInput,
Button
} from 'react-native';
import { Client, Message } from 'react-native-paho-mqtt';
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
export default class App extends Component<{}> {
constructor(){
super();
const myStorage = {
setItem: (key, item) => {
myStorage[key] = item;
},
getItem: (key) => myStorage[key],
removeItem: (key) => {
delete myStorage[key];
},
};
const client = new Client({ uri: "wss://m12.cloudmqtt.com:31839/", clientId: 'clientIdReactNative' + (new Date()).getTime(), storage: myStorage });
client.on('messageReceived', (entry) => {
console.log(entry);
this.setState({message: [...this.state.message, entry.payloadString]});
});
client.on('connectionLost', (responseObject) => {
if (responseObject.errorCode !== 0) {
console.log(responseObject.errorMessage);
this.setState({error: 'Lost Connection', isConnected: false});
}
});
this.connect(client)
.then(() => {
console.log('connect!');
this.setState({isConnected: true, error: ''})
})
.catch((error)=> {
console.log(error);
});
this.state = {
client,
message: [''],
messageToSend:'',
isConnected: false
}
}
connect(client){
return client.connect({
useSSL: true,
userName: 'azebvdny',
password: 'MsULac9Uhig0'
})
.then(() => {
client.subscribe('S/ReactMQTT');
})
}
onConnect = () => {
const { client } = this.state;
client.subscribe('ReactMQTT');
this.pushText('connected');
};
pushText = entry => {
const { message } = this.state;
this.setState({ message: [...message, entry] });
};
onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
onMessageArrived(message) {
console.log("onMessageArrived:"+message.payloadString);
}
componentWillMount(){
}
sendMessage(){
var message = new Message(this.state.messageToSend);
message.destinationName = "S/ReactMQTT";
if(this.state.isConnected){
this.state.client.send(message);
}else{
this.connect(this.state.client)
.then(() => {
console.log('connect!');
this.state.client.send(message);
this.setState({error: '', isConnected: true});
})
.catch((error)=> {
console.log(error);
this.setState({error: error});
});
}
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Nativess!
</Text>
<Text style={styles.instructions}>
Message: {this.state.message.join(' --- ')}
</Text>
<Text style={{color: 'red'}}>
{this.state.error}
</Text>
{ this.state.isConnected ?
<Text style={{color: 'green'}}>
Connected
</Text> : null
}
<TextInput
value={this.state.messageToSend}
onChangeText={(value => this.setState({messageToSend: value}))}
placeholder="Type here... "
style={styles.input} />
<Button onPress={this.sendMessage.bind(this)} title="Send Message" />
</View>
);
}
}
const styles = StyleSheet.create({
...
});
Any help would be greatly appreciated.
react-native-paho-mqtt only supports WebSocket.
because react-native-paho-mqtt doesn't support raw TCP out of the box
If you use real-native-tcp to configure the client, it may be possible on the code.
The example of a module tells us it's not possible.
test('should fail to create a new client with an invalid ws uri', function () {
let client = null;
let error;
try {
client = new Client({ uri: 'http://example.com', clientId: 'testclientid', webSocket, storage });
} catch (err) {
error = err;
}
expect(client).toBe(null);
expect(error).not.toBe(null);
For new googlers: you can use react_native_mqt.
After you managed to properly install the library, for example, this could be your App.js:
import React, { Component } from 'react';
import init from 'react_native_mqtt';
import { AsyncStorage,
StyleSheet,
Text,
View,
TextInput,
Button,
Alert
} from 'react-native';
init({
size: 10000,
storageBackend: AsyncStorage,
defaultExpires: 1000 * 3600 * 24,
enableCache: true,
sync: {},
});
export default class App extends Component {
constructor(){
super();
this.onMessageArrived = this.onMessageArrived.bind(this)
this.onConnectionLost = this.onConnectionLost.bind(this)
const client = new Paho.MQTT.Client('yourURL', yourPort, 'someClientID',);
client.onMessageArrived = this.onMessageArrived;
client.onConnectionLost = this.onConnectionLost;
client.connect({
onSuccess: this.onConnect,
useSSL: false ,
userName: 'yourUser',
password: 'yourPass',
onFailure: (e) => {console.log("here is the error" , e); }
});
this.state = {
message: [''],
client,
messageToSend:'',
isConnected: false,
};
}
onMessageArrived(entry) {
console.log("onMessageArrived:"+message.payloadString);
this.setState({message: [...this.state.message, entry.payloadString]});
}
onConnect = () => {
const { client } = this.state;
console.log("Connected!!!!");
client.subscribe('hello/world');
this.setState({isConnected: true, error: ''})
};
sendMessage(){
message = new Paho.MQTT.Message(this.state.messageToSend);
message.destinationName = "hello/world";
if(this.state.isConnected){
this.state.client.send(message);
}else{
this.connect(this.state.client)
.then(() => {
this.state.client.send(message);
this.setState({error: '', isConnected: true});
})
.catch((error)=> {
console.log(error);
this.setState({error: error});
});
}
}
onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
this.setState({error: 'Lost Connection', isConnected: false});
}
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native MQTT!
</Text>
<Text style={styles.instructions}>
Message: {this.state.message.join(' --- ')}
</Text>
<Text style={{color: 'red'}}>
{this.state.error}
</Text>
{ this.state.isConnected ?
<Text style={{color: 'green'}}>
Connected
</Text> : null
}
<TextInput
value={this.state.messageToSend}
onChangeText={(value => this.setState({messageToSend: value}))}
placeholder="Type hereee..."
style={styles.input} />
<Button onPress={this.sendMessage.bind(this) } title="Send Message" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
button: {
padding: 10,
alignItems: 'center',
justifyContent: 'center',
},
buttonLabel: {
color: 'blue',
},
input:{
width: 300
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
Replace the URL and other stuff with your own. For example, you have to put it like this:
const client = new Paho.MQTT.Client('something.something.ir', 1883, '123456');
When pressing the Button nothing happens. The picture shows a warning and I can get rid of that if I change the
onPress={this._onSearchPressed}
to
onPress={() => this._onSearchPressed()}
But now when pressing the Button i get the error you see on the picture below like "undefined is not a function..".
How do I call a onPress correctly?
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
Text,
TextInput,
View,
Button,
ActivityIndicator,
Image,
} from 'react-native';
type Props = {};
function urlForQueryAndPage(key, value, pageNumber) {
const data = {
country: 'uk',
pretty: '1',
encoding: 'json',
listing_type: 'buy',
action: 'search_listings',
page: pageNumber,
};
data[key] = value;
const querystring = Object.keys(data)
.map(key => key + '=' + encodeURIComponent(data[key]))
.join('&');
return 'https://api.nestoria.co.uk/api?' + querystring;
}
export default class SearchPage extends Component<Props> {
static navigationOptions = {
title: 'Property Finder',
};
constructor(props) {
super(props);
this.state = {
searchString: 'london',
isLoading: false,
};
}
_onSearchTextChanged = (event) => {console.log('_onSearchTextChanged');
this.setState({ searchString: event.nativeEvent.text });
console.log('Current: '+this.state.searchString+', Next: '+event.nativeEvent.text);
_executeQuery = (query) => {
console.log(query);
this.setState({ isLoading: true });
};
_onSearchPressed = () => {
const query = urlForQueryAndPage('place_name', this.state.searchString, 1);
this._executeQuery(query);
};
};
render() {
console.log('SearchPage.render');
const spinner = this.state.isLoading ? <ActivityIndicator size='large'/> : null;
return (
<View style={styles.container}>
<Text style={styles.description}>
Search for houses to buy!
</Text>
<Text style={styles.description}>
Search by place-name or postcode.
</Text>
<View style={styles.flowRight}>
<TextInput
underlineColorAndroid={'transparent'}
style={styles.searchInput}
value={this.state.searchString}
onChange={this._onSearchTextChanged}
placeholder='Search via name or postcode'/>
<Button
onPress={this._onSearchPressed}
color='#48BBEC'
title='Go'>
</Button>
</View>
<Image source={require('./Resources/house.png')} style={styles.image}/>
{spinner}
</View>
);
}
}
const styles = StyleSheet.create({
description: {
marginBottom: 20,
fontSize: 18,
textAlign: 'center',
color: '#a56565'
},
flowRight: {
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'stretch',
},
searchInput: {
height: 36,
padding: 4,
marginRight: 5,
flexGrow: 1,
fontSize: 18,
borderWidth: 1,
borderColor: '#48BBEC',
borderRadius: 8,
color: '#48BBEC',
},
container: {
padding: 30,
marginTop: 65,
alignItems: 'center'
},
image: {
width: 217,
height: 138,
},
});
Okay, I think I might have found the error.
Here inside your code
_onSearchTextChanged = (event) => {console.log('_onSearchTextChanged');
this.setState({ searchString: event.nativeEvent.text });
console.log('Current: '+this.state.searchString+', Next: '+event.nativeEvent.text);
_executeQuery = (query) => {
console.log(query);
this.setState({ isLoading: true });
};
_onSearchPressed = () => {
const query = urlForQueryAndPage('place_name', this.state.searchString, 1);
this._executeQuery(query);
};
};
You are nesting these two functions
_executeQuery = (query) => {
console.log(query);
this.setState({ isLoading: true });
};
_onSearchPressed = () => {
const query = urlForQueryAndPage('place_name', this.state.searchString, 1);
this._executeQuery(query);
};
inside your _onSearchTextChanged function. You probably might want to do something like this
_onSearchTextChanged = (event) => {console.log('_onSearchTextChanged');
this.setState({ searchString: event.nativeEvent.text });
console.log('Current: '+this.state.searchString+', Next: '+event.nativeEvent.text);
}
_executeQuery = (query) => {
console.log(query);
this.setState({ isLoading: true });
};
_onSearchPressed = () => {
const query = urlForQueryAndPage('place_name', this.state.searchString, 1);
this._executeQuery(query);
};
Notice the closing } of your first function