In my RN application, I have the following code.
import { PermissionsAndroid } from 'react-native';
export default new Promise(() => {
return PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_CONTACTS, {
title: 'Contacts List',
message: 'Canvas would like to view your contacts',
});
});
What I want to do is, I want to return, if the promise is successful or not. Then, I can get the promised status and handle the android permissions according to that. But the current code returns this.
40
:
0
_55
:
null
_65
:
0
_72
:
null
__proto__
:
Object
What am I doing wrong here?
Because the function for the current authority is asynchronous, if the result is returned immediately, the value is returned before the result is obtained. Therefore, it is advisable to check the value after putting it in the variable. Or, it is desirable to receive the results after conversion in a synchronous fashion.
That object at the end looks like the value you want.
example (Use Async )
import {PermissionsAndroid} from 'react-native';
async function requestCameraPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Cool Photo App Camera Permission',
message:
'Cool Photo App needs access to your camera ' +
'so you can take awesome pictures.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('You can use the camera');
} else {
console.log('Camera permission denied');
}
} catch (err) {
console.warn(err);
}
}
example (Use Sync )
import {PermissionsAndroid} from 'react-native';
function requestCameraPermission() {
try {
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Cool Photo App Camera Permission',
message:
'Cool Photo App needs access to your camera ' +
'so you can take awesome pictures.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
).then(result => { console.log(result) }).catch(err => console.log(err));
} catch (err) {
console.warn(err);
}
}
const requestPermission = async (requestedType) => {
try {
return await PermissionsAndroid.requestMultiple(requestedType);
} catch (e) {
return e;
}
};
const permissionsRequired = [PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION];
const permissionResponse = yield call(requestPermission, permissionsRequired);
Try above code. Hope this help.
Related
I have a route like http://localhost:3000/admin/video/edit/5 and the controller looks like this
albumEdit: async (req, res) => {
const editInfoId = req.params.id;
await Movie.findOne({ where: { id: editInfoId } }).then((movie) => {
if (movie) {
res.render('admin/movies/edit', { title: 'Edit Movie On Page One', movie });
}
});
},
for the testing purpose when I type the wrong id after edit/ then the process is freezing after some time I am getting 500 errors.
how to prevent this if someone tries to break my app with the wrong id in the URL? I want something like if anyone tries to do this application redirect to an error page.
I am new in node js express js I need some info.
Your route will freeze if movie is falsy or if fineOne results in an error because for both of these cases you don't send any response.
after some time I am getting 500 errors.
If you run your node server behind a web server then this 500 is due to a timeout because your router does not send a response.
how to prevent this if someone tries to break my app with the wrong id in the URL? I want something like if anyone tries to do this application redirect to an error page.
As with any programming language or code, make sure you handle all control flows and possible exceptions.
Besides that, if you use await you in most of the cases don't want to use .then.
albumEdit: async (req, res) => {
const editInfoId = req.params.id;
try {
let movie = await Movie.findOne({
where: {
id: editInfoId
}
})
if (movie) {
res.render('admin/movies/edit', {
title: 'Edit Movie On Page One',
movie
});
} else {
// either the if is not necessary or you have to also handle the else cases
// send some error response
res.send('error')
}
} catch (err) {
// send some error response
res.send('error')
}
}
For completeness, this is how where you would need to do changes in your code, but as said above don't mix await and then:
albumEdit: async (req, res) => {
const editInfoId = req.params.id;
try {
await Movie.findOne({
where: {
id: editInfoId
}
}).then((movie) => {
if (movie) {
res.render('admin/movies/edit', {
title: 'Edit Movie On Page One',
movie
});
} else {
// either the if is not necessary or you have to also handle the else cases
// send some error response
res.send('error')
}
});
} catch (err) {
// send some error response
res.send('error')
}
}
needing a guide for how to layout functionality for a React Native app that's pairing with an ESP32 that will eventually feed back weight readings using read Characteristic, and be able to toggle a DI via write to a characteristic.
i can currently scan and connect to the ESP32 and show the values from the ESP32 (random changing values for now) and also toggle the LED via changing a hardcoded value. But i want to be able to do this via a button in the app.
const scanDevices = () => {
//set isLoading to true to show activity Indicator
setIsLoading(true);
//scan for devices, (UUIDs, ScanOptions(error, device))
manager.startDeviceScan(null, null, (error, device) => {
if (error) {
console.log("Error in scanning", error.message)
return;
}
if (device) {
//if a device is scanned, add the name & id details into the scannedDevice object via reducer
dispatch({type: 'DEVICE_ADD', payload: {name: device.name, id: device.id}});
}
});
//end scan after 3 seconds, stop the activity indicator swirly thing
setTimeout(() => {
console.log("Scan timeout after 5 seconds");
manager.stopDeviceScan();
setIsLoading(false);
}, 5000);
};
const deviceConnect = (device) => {
console.log("Connecting to:", device.name, device.id);
setIsConnected(true);
setConnectedDevice(device);
manager.connectToDevice(device.id)
.then((device) => {
console.log("Discovering all services & chars");
return device.discoverAllServicesAndCharacteristics()
}).then((device) => {
// console.log("Write Value inside deviceConnect:", writeValue)
console.log("Device:", device.name, "has been connected.");
return deviceNotifications(device, writeValue);
}).catch((error) => {
console.log("device connect error:", device.name, error)
//JSON.stringify(error)
});
};
const deviceNotifications = async (device, writeValue) => {
const service = "af493e2a-f002-11eb-9a03-0242ac130003";
const characteristicTX = "af49423a-f002-11eb-9a03-0242ac130003";
const characteristicRX = "af49414a-f002-11eb-9a03-0242ac130003";
if (device) {
try {
device.monitorCharacteristicForService(service, characteristicTX, (error, characteristic) => {
if (error) {
console.log(error);
} else {
setCharacteristicValue(() => {
return [{id: uuid.v4(), value: (base64.decode(characteristic.value))}];
})}
});
device.writeCharacteristicWithResponseForService(service, characteristicRX, base64.encode(writeValue));
console.log("Writing to RX:", writeValue);
}
catch (err) {
console.log("deviceNotification catch error:", err);
}
};
}
I'm getting pretty confused trying to sort through the [ble-plx documentation][1] ([github wiki][2])
Currently the only way i can get the LED to turn on/off, is i have the LED toggle section inside the deviceNotifications async function and have to manually change the value that's being encoded and written in the code itself, rather than from the App UI using an useState value.
I tried using the useState toggle off a button (which toggled the value and logged out OK), and then re-calling the deviceConnect function, but the commented out console.log in the .then promise section didn't work past the first one, returning which turned the LED on (writing 'A' to the characteristic).
thanks for any help in advance, i know a lot of these ble-plx questions go unanswered.
//this is at a top level inside the main function
const [writeValue, setWriteValue] = useState('A');
const toggleLED = () => {
if (writeValue == 'B') {
setWriteValue('A');
console.log("Toggling write value:", writeValue);
} else {
setWriteValue('B')
console.log("Toggling write value", writeValue)
};
};
[1]: https://dotintent.github.io/react-native-ble-plx/
[2]: https://github.com/dotintent/react-native-ble-plx/wiki
[3]: https://www.polidea.com/blog/ReactNative_and_Bluetooth_to_An_Other_level/
I am working on react native application. There I have to fetch user locations like multiple if user moves/navigates from one place to other. This is working fine, but, If user disables location permission after some time like user goes to settings there disabled permission, I have to show some button like enable location and again Once user tap on that button It should ask to Request Permission for location.
But, If user first time gives permission and later in some time if he disables permission, The popup for Request permission not showing popup in Android on tap of button.
I am using following library to fetch user location details.
import Geolocation from 'react-native-geolocation-service';
// button on click method following
enableLocationHandler = () => {
if (Platform.OS === 'android') {
this.requestLocationPermissions();
} else {
Linking.openURL('app-settings:');
this.getLatitudeLongitude();
}
}
requestLocationPermissions = async () => {
if (Platform.OS === 'android') {
this.getLatitudeLongitude();
} else {
Geolocation.requestAuthorization();
this.getLatitudeLongitude();
}
}
getLatitudeLongitude() {
Geolocation.getCurrentPosition((position) => {
const initialPosition = JSON.stringify(position);
},
(error) => {
if (error.code === 1) {
this.setState({ errorMessage: 'Location permission is denied', isLoading: false });
Geolocation.clearWatch(this.watchID);
}
},
{ enableHighAccuracy: true, distanceFilter: 100, timeout: 20000, maximumAge: 1000 }
);
this.watchID = Geolocation.watchPosition((position) => {
// this.showLoader();
// console.log('position', position);
});
}
Any suggestions?
IN this plugin react-native-geolocation-service, There is no declared run time permission in android. that's by in android , permission dialog is not showing .
To resolve this issue add this permission before request for fetch location
import {PermissionsAndroid} from 'react-native';
async function requestAccessLocationPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS. ACCESS_FINE_LOCATION,
{
title: 'Application wants location Permission',
message:
'Application wants location Permission',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
} else {
}
} catch (err) {
console.warn(err);
}
}
this will helps you, it helps me.
No Location Permission pop up in ios app nor can see Permissions options in the settings of the App
Works fine on Android. As I can use PermissionsAndroid to get the permissions.
Already used the following options in the info.plist by looking at the other answers. Few answers only mentioned about android.
info.plist
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Location Permission</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Location Permission</string>
<key>NSLocationUsageDescription</key>
<string>GPS data is required to...</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location Permission</string>
codeinthefile.js
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: "Geolocation Permission",
message: "App needs access to your phone's location.",
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
Geolocation.getCurrentPosition(
position => {
Geocoder.from({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
})
.then(json => {
console.log(json);
})
.catch(error => {
console.log(error);
});
},
error => {
console.log(error);
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
);
} else {
console.log('Location permission not granted!);
}
} catch (err) {
console.log('Location permission not granted!)
}
If by using the above-mentioned values in info.plist I should get the access to location then there should not be an error of no permission granted.
Don't use PermissionAndroid in iOS, is enough to put the permission requirement in the info.plist,
try something like,
if(Platform.OS === "ios"){
// your code using Geolocation and asking for authorisation with
geolocation.requestAuthorization()
}else{
// ask for PermissionAndroid as written in your code
}
Thank you, Doug and David, Based on your suggestion I have made then changes to my code in the following way which worked for me:
if(Platform.OS === 'ios'){
Geolocation.requestAuthorization();
this.getGeoLocation();
}else {
let granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: "App Geolocation Permission",
message: "App needs access to your phone's location.",
}
);
if (androidGranted === PermissionsAndroid.RESULTS.GRANTED) {
this.getGeoLocation();
} else {
console.log('Location permission not granted!!!!');
}
}
Use below for both android and ios permissions .
import {Platform} from 'react-native';
import {request, PERMISSIONS, RESULTS} from 'react-native-permissions';
....
export async function getLocationPermissions() {
const granted = await request(
Platform.select({
android: PERMISSIONS.ANDROID.ACCESS_COARSE_LOCATION,
ios: PERMISSIONS.IOS.LOCATION_WHEN_IN_USE,
}),
{
title: 'DemoApp',
message: 'DemoApp would like access to your location ',
},
);
return granted === RESULTS.GRANTED;
}
....
// usage
const granted = await getLocationPermissions();
I'm trying to enable sound for my Firebase push notifications and I'm not sure if there is code in the App Delegate which I need to implement, or if the code in my index.js is wrong.
I thought there was something I needed to import in AppDelegate related to sound, but all the guides I've found for implementing push notifications only have the basic code where [options] contains the only thing related to the notification's sound.
index.js Code:
var notification = {
notification: {
title: conversation.conversationName,
body: user.username + ': ' + message.text,
sound: 'default'
},
topic: topic
}
App Delegate Code: Function called in didFinishLaunchingWithOptions.
import UIKit
import Firebase
import UserNotifications
private func attemptRegisterForNotifications(application: UIApplication) {
Messaging.messaging().delegate = self
UNUserNotificationCenter.current().delegate = self
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
if settings.authorizationStatus == .authorized {
// Push notifications already authorized, do nothing
print ("push notifications authorized")
} else if settings.authorizationStatus == .notDetermined {
// User hasn't specified notification status
UNUserNotificationCenter.current().requestAuthorization(options: options, completionHandler: { (granted, error) in
if let error = error {
print ("Failed to request authorization:", error)
return
}
guard granted else {return}
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
})
} else if settings.authorizationStatus == .denied {
// User has denied notifications
UNUserNotificationCenter.current().requestAuthorization(options: options, completionHandler: { (granted, error) in
if let error = error {
print ("Failed to request authorization:", error)
return
}
let alertController = UIAlertController(title: "Enable Push Notifications", message: "Enable push notifications for optimal chat experience", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in
guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
return
}
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
})
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
alertController.preferredAction = settingsAction
DispatchQueue.main.async {
self.window?.rootViewController?.present(alertController, animated: true, completion: nil)
}
})
}
}
}