expo-camera: Error: Permissions module is null - react-native

I have an error in console after to install expo-camera.
expo install expo-camera
add permission in android manifest
add module expo camera in maven
allprojects {
repositories {
// * Your other repositories here *
// * Add a new maven block after other repositories / blocks *
maven {
// expo-camera bundles a custom com.google.android:cameraview
url "$rootDir/../node_modules/expo-camera/android/maven"
}
}
}
start the protect
click on the button to show camera ... error in log
Error: Permissions module is null.
Permission:
<uses-permission android:name="android.permission.CAMERA" />
update 1 :
I test with this code example to check my permission
https://reactnative.dev/docs/permissionsandroid
my example function
// state local
const [hasPermission, setHasPermission] = useState(null);
// function
const requestCameraPermission = async () => {
console.log('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) {
setHasPermission(true)
console.log("You can use the camera");
} else {
console.log("Camera permission denied");
setHasPermission(false)
}
} catch (err) {
console.warn(err);
}
};
// result of requestCameraPermission : You can use the camera
// Error : Attempt to invoke interface method 'boolan expo.modules.interfaces.permission.Permission.hasGrantedPermissions(java.lang.string[]) on a null object reference
I make something wrong ?
thanks for help

If you did just these steps, you have to do more things to make it works on Android device.
Github page says:
Adjust the android/build.gradle to add a new maven block after all other repositories as described below:
allprojects {
repositories {
// * Your other repositories here *
// * Add a new maven block after other repositories / blocks *
maven {
// expo-camera bundles a custom com.google.android:cameraview
url "$rootDir/../node_modules/expo-camera/android/maven"
}
}
}
But before do that, you should:
For bare React Native projects, you must ensure that you have installed and configured the react-native-unimodules package before continuing.

Related

Expo facebook login fails: error : server with the specified hostname could not be found?

UPDATE: it works in the IOS simulator, but only doesnt work in my expo go app.
I have an expo react native managed app. I tried to implement the facebook login but I always get the following error:
my code (there should not be problems with it, its just the sample code from expo)
const AuthScreen = () => {
import * as Facebook from 'expo-facebook';
const loginWithFacebook = async () => {
try {
await Facebook.initializeAsync({
appId: '<MYAPPID>',
});
const {type, token, expirationDate, permissions, declinedPermissions} =
await Facebook.logInWithReadPermissionsAsync({
permissions: ['public_profile'],
});
if (type === 'success') {
const response = await fetch(`https://graph.facebook.com/me?access_token=${token}`);
Alert.alert('Logged in!', `Hi ${(await response.json()).name}!`);
} else {
// type === 'cancel'
}
} catch ({message}) {
alert(`Facebook Login Error: ${message}`);
}
};
return (
<FontAwesome.Button name="facebook" onPress={loginWithFacebook}>Login With Facebook</FontAwesome.Button>
)
};
What I did so when registering my app:
in facebook developers I created my app 'rainy'.
In settings/basic I added IOS and Android.
a. in IOS I only added host.exp.Exponent as the Bundle ID
b. In android I only added the hash key: rRW++LUjmZZ+58EbN5DVhGAnkX4= (I couldnt find that hash on expo docs anymore but found it elsewhere and it should be up to date)
in app.json I added infoPlist with properties to ios as following:
...
"ios": {
"supportsTablet": true,
"infoPlist": {
"facebookScheme": "fb<MYAPPID>",
"facebookAppId": "<MYAPPID>",
"FacebookClientToken": "abcxxxxx", //got it from Settings > Advanced > Client Token
"facebookDisplayName": "rainy",
"facebookAutoLogAppEventsEnabled": false,
"facebookAdvertiserIDCollectionEnabled": false
}
},
...
I wasnt sure but also (after getting the error) tried to add to Valid OAuth Redirect URIs the following: https://auth.expo.io/#/rainy. not sure if even needed but the error is still the same
Also I expo installed expo-facebook.
Did I miss any step or did something wrong? Thank you!!

Share a URL as post in Facebook App from React-Native App

I have a React-native app, from which I want share my website's URL in a Facebook post.
My current code is :
import Share from "react-native-share";
const shareToFacebook = async () => {
const shareOptions = {
social: Share.Social.FACEBOOK,
message: "Test message",
url: "https://example.com/",
};
try {
const ShareResponse = await Share.shareSingle(shareOptions);
console.log(ShareResponse);
} catch (error) {
console.log("Error =>", error);
}
};
but this solution ,opens Facebook in the browser. Is there any way to open the actual Facebook app ?
Facebook offers an SDK for sharing posts, you can use that SDK with react-native-fbsdk-next library. It shows an in-app modal. I think showing an in-app modal is better than the open the Facebook app or open a browser because some people do not have Facebook on their phones.
You can test the share function before installing the library, follow below steps:
# clone the react-native-fbsdk-next
git clone https://github.com/thebergamo/react-native-fbsdk-next.git
# go to the test project
cd RNFBSDKExample
# install dependencies
npm install
# run the project
npm run android
Example code (from README page):
// ...
import { ShareDialog } from 'react-native-fbsdk-next';
// ...
// Build up a shareable link.
const shareLinkContent = {
contentType: 'link',
contentUrl: "https://facebook.com",
contentDescription: 'Wow, check out this great site!',
};
// ...
// Share the link using the share dialog.
shareLinkWithShareDialog() {
var tmp = this;
ShareDialog.canShow(this.state.shareLinkContent).then(
function(canShow) {
if (canShow) {
return ShareDialog.show(tmp.state.shareLinkContent);
}
}
).then(
function(result) {
if (result.isCancelled) {
console.log('Share cancelled');
} else {
console.log('Share success with postId: '
+ result.postId);
}
},
function(error) {
console.log('Share fail with error: ' + error);
}
);
}
Read more about Facebook Sharing Feature.

react-native 0.59 migrated to API 29 how to request permission on location

I'm using rn 0.59.
Currently on Android API 28, when you request a permission,
It has an option for 'Allow all the time'
But when I shifted to API 29.
It is gone on the permission box.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
export async function requestLocationPermission() {
try {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
return PermissionsAndroid.RESULTS.GRANTED;
} else if (granted === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN) {
return PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN;
} else {
return PermissionsAndroid.RESULTS.DENIED;
}
} catch (err) {
return false;
}
};
how can you access the background location here, since it has only ACCESS_FINE_LOCATION?
Thanks!
https://developer.android.com/training/location/permissions#request-background-location
On Android 11 (API level 30) and higher, however, the system dialog doesn't include the Allow all the time option. Instead, users must enable background location on a settings page.
You can help users navigate to this settings page by following best practices when requesting the background location permission. The process for granting the permission depends on your app's target SDK version.
Open settings using the same permissions library that you're using :
https://github.com/zoontek/react-native-permissions#opensettings
import {openSettings} from 'react-native-permissions';
openSettings().catch(() => console.warn('cannot open settings'));
I created a bridge on android
int permissionCheck = ContextCompat.checkSelfPermission(this.getReactApplicationContext(),
Manifest.permission.ACCESS_BACKGROUND_LOCATION);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
promise.resolve(true);
} else {
final Activity activity = getCurrentActivity();
ActivityCompat.requestPermissions(
activity,
new String[]{
Manifest.permission.ACCESS_BACKGROUND_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
},
MY_PERMISSIONS_REQUEST_LOCATION
);
promise.resolve(false);
}

ReactNative - PermissionDialog after launching app - 'remove' won't work

In ReactNative app, we are using Storage permission to view/save pictures. So we're getting runtime permission where its required. But the strange thing is, it was asking permission in Splash screen itself, where we didn't ask permission. Then I came across the following fix:
https://facebook.github.io/react-native/docs/removing-default-permissions
Removing Permission using 'remove':
<uses-permission tools:node="remove" android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
But the problem is, If I do like this, I can't get those permissions where its needed.
So ideally, I would like to remove permission dialog in SplashScreen and add only where its required. Please advise.
This answer might seems bit odd to you, but I was in same situation, where I need to use Storage Permission of zip extraction in my current application.
The way I manage things are as follows:
I asked permission in Android Code using React Native Bridging
concept.
I add delay to show permission dialog on next screen (i.e
after splash screen)
When user grant me permission I started extraction and overlay loader to full screen.
When user denied the storage permission I closed the application.
Check the code below
NextScreen After Splash
this.onZipExtracted = this.onZipExtracted.bind(this)
componentDidMount() {
setTimeout(() => {
Splash.hide()
}, Platform.OS == 'ios' ? 1000 : 500);
if (Platform.OS === 'android') {
AsyncStorage.getItem("Extraction",(error,result)=>{
if(result != 'done'){
this.setState({
animating:true
})
setTimeout(() => {
expandPath.callReactMethod(this.onZipExtracted, (error) => {
console.log("Activation Inside Callback"+JSON.stringify(error))
//Do your stuff
})
}, 500)
}
})
}
}
onZipExtracted(success){
console.log("Activation Callback Extract Success -> "+JSON.stringify(success))
this.setState({
set loader flag
})
AsyncStorage.setItem("Extraction","done")
Actions.replace('Screen to replace')
}
Java Code for Permission
I used Dexter Android Permission Library
#ReactMethod
public void callReactMethod(Callback successCallback, Callback errorCallback){
callUserPermission(getCurrentActivity(), successCallback,errorCallback);
}
private void callUserPermission(Activity currentActivity, Callback successCallback, Callback errorCallback) {
Dexter.withActivity(getCurrentActivity())
.withPermissions(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(new MultiplePermissionsListener() {
#Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
// check if all permissions are granted
if (report.areAllPermissionsGranted()) {
Log.i(TAG, "onPermissionsChecked: -> Granted");
// Do your stuff here
}
} else {
currentActivity.finishAffinity();
System.exit(0);
}
// check for permanent denial of any permission
if (report.isAnyPermissionPermanentlyDenied()) {
// permission is denied permenantly, navigate user to app setting
}
}
#Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions,
PermissionToken token) {
token.continuePermissionRequest();
}
})
.onSameThread()
.check();
}

React-Native: Can't receive expo push notification on stand alone app

This is ss from standalone app, its gettings expo token but for some reason it wont show notifications
I can't receive push notification on my standalone apps and if someone else used the app from expo (not my phone) then he won't receive it either,
For some reason only i receive it ..that too on expo client and if i install the apk on my phone, then i get the error....
In these all situations the error is same,
{
"data": {
"status": "error",
"message": "SNS failed to send the notification (reason: EndpointDisabled, status code: 400).",
"details": {
"error": "DeviceNotRegistered",
"sns": {
"statusCode": 400,
"reason": "EndpointDisabled",
"__message": "Endpoint is disabled"
}
}
}
}
my notification js
import { Permissions, Notifications } from 'expo';
import { AsyncStorage } from 'react-native';
import axios from 'axios';
import {
IUSTCONNECT_URL
} from '../actions/types';
const server = IUSTCONNECT_URL;
export default async function registerForPushNotificationsAsync() {
const { status: existingStatus } = await Permissions.getAsync(
Permissions.NOTIFICATIONS
);
let finalStatus = existingStatus;
// only ask if permissions have not already been determined, because
// iOS won't necessarily prompt the user a second time.
if (existingStatus !== 'granted') {
// Android remote notification permissions are granted during the app
// install, so this will only ask on iOS
const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
finalStatus = status;
}
// Stop here if the user did not grant permissions
if (finalStatus !== 'granted') {
return;
}
// Get the token that uniquely identifies this device
let token = await Notifications.getExpoPushTokenAsync();
console.log(token);
await AsyncStorage.setItem('notificationToken', token);
const adminFlag = await AsyncStorage.getItem('admin');
try {
const { data } = await axios.post(`${server}/admin/app_bridge/user.php`, {
job: 'updateExpoToken',
admin: adminFlag,
token: token
});
if(data.trim() === 'success') {
console.log('expo push notification token sent:');
} else {
console.log('error sending notification token:');
console.log(data);
}
} catch (e) {
console.log(e);
}
}
and i am calling registerForPushNotificationsAsync() on my child tab,
Everything works well for my expo app...rest it doesn't...
Any help?
The issue is with the device. you can see in error DeviceNotRegistered.
see expo docs here.
DeviceNotRegistered: the device cannot receive push notifications
anymore and you should stop sending messages to the given Expo push
token.
The problem is that in docs no information why this error is happening. Try with some other device's.
if you develop with firebase you need update your token, the steps are:
1 in your page of project firebase, select option setting.
2 navigate to option project settings.
3 select option cloud messasging.
4 on credetial of project copy the token.
5. in your terminal in root directory of project type:
expo push:android:upload --api-key <your token>
for more information visit
enter link description here
try send push notification Manually
enter link description here
i'm working with sdk 37.0.0