Missing MEDIA_LIBRARY permissions - javascript

I making an app using react native expo, onPress I want to download a .vcf or .pdf file on specified folder which is I fetched from server. but when I click onPress I get following errors in console
I able to download Images but when it comes to .vcf or pdf file facing below error.
MediaLibrary.createAlbumAsync("xFolderName", asset);
xFolderName where Im trying to store my .vcf or .pdf file, following path is created while saving an Images same for .vcf file Android-> Pictures -> xFolderName
[Unhandled promise rejection: Error: MediaLibrary.createAlbumAsync
must be called with an asset on Android.]
at node_modules/expo-media-library/build/MediaLibrary.js:302:14 in createAlbumAsync
at node_modules/expo-media-library/build/MediaLibrary.js:295:7 in createAlbumAsync
at components/ngo/ECard.js:98:8 in FileSystem.downloadAsync.then$argument_0
[Unhandled promise rejection: Error: Missing MEDIA_LIBRARY
permissions.]
at node_modules/react-native/Libraries/BatchedBridge/NativeModules.js:106:50 in promiseMethodWrapper
at node_modules/expo-modules-core/build/NativeModulesProxy.native.js:15:23 in moduleName.methodInfo.name
at node_modules/expo-media-library/build/MediaLibrary.js:148:24 in createAssetAsync
at node_modules/expo-media-library/build/MediaLibrary.js:141:7 in createAssetAsync
at components/ngo/ECard.js:97:22 in FileSystem.downloadAsync.then$argument_0
App.js
import { Header } from "react-native/Libraries/NewAppScreen";
import { StatusBar } from "expo-status-bar";
import {
StyleSheet,
Text,
View,
Button,
Image,
TouchableOpacity,
ScrollView,
Modal,
Share,
ImageBackground,
} from "react-native";
import React, { useState } from "react";
import { API_URL } from "#env";
import { Icon, SocialIcon } from "#rneui/themed";
import * as FileSystem from "expo-file-system";
import * as Permissions from "expo-permissions";
import * as MediaLibrary from "expo-media-library";
import Toast from "react-native-root-toast";
export default function App(props) {
const [apiData, setApiData] = React.useState({
xxxname: "",
});
const downloadFile = () => {
FileSystem.downloadAsync(
`${API_URL}/xpath/xpath?slug=${apiData.slug}`,
FileSystem.documentDirectory + apiData.xname + ".vcf"
)
.then(({ uri }) => {
const asset = MediaLibrary.createAssetAsync(uri);
MediaLibrary.createAlbumAsync("xFolderName", asset);
Toast.show("Download Completed");
})
.catch((error) => {
console.error(error);
});
};
return (
<View>
<TouchableOpacity
style={styles.addButton}
onPress={() => downloadFile()}
>
<Icon
color={"white"}
name="file-download"
/>
<Text style={styles.addButtonText}>Download</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
addButton: {
width: "30%",
margin: 10,
height: 55,
backgroundColor: "#3b82f6",
borderRadius: 15,
alignItems: "center",
justifyContent: "center",
elevation: 8,
},
addButtonText: {
color: "#fff",
fontSize: 18,
},
});

Related

Why my app is only showing loading screen? and warn me TypeError: undefined is not an object (evaluating '_asyncStorage.AsyncStorage.getItem')

Why my app is only showing loading screen? when i am running my app than its only loading and not showing other screens and showing a WARN that
` WARN Possible Unhandled Promise Rejection (id: 0): TypeError: undefined is
i think it has problem with this code
import React, { useEffect } from 'react';
import { View, ActivityIndicator, StyleSheet} from 'react-native';
import { AsyncStorage } from '#react-native-async-storage/async-storage';
import { useDispatch } from 'react-redux';
import Colors from '../constants/Colors';
import * as authActions from '../store/actions/auth';
const StartupScreen = props => {
const dispatch = useDispatch();
useEffect(() => {
const tryLogin = async () => {
const userData = await AsyncStorage.getItem('userData');
if (!userData) {
// props.navigation.navigate('Auth');
dispatch(authActions.setDidTryAutoLogin());
return;
}
const transformedData = JSON.parse(userData);
const { token, user } = transformedData;
// props.navigation.navigate('Shop');
dispatch(authActions.authenticate(user, token));
};
tryLogin();
}, [dispatch])
return (
<View style={styles.screen}>
<ActivityIndicator size="large" color={Colors.primary} />
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
export default StartupScreen;
According to the docs you import is wrong.
This:
import { AsyncStorage } from '#react-native-async-storage/async-storage';
should be
import AsyncStorage from '#react-native-async-storage/async-storage';
Basically, what you are trying to do with {AsyncStorage} is you are importing "part" of the exported code called AsyncStorage. That is why the error says:
_asyncStorage.AsyncStorage.getItem') (asyncStorage mentioned twice) and you need the entire object out of the package.

React navigation content size too narrow

Hi I am implementing react navigation in a react native app, and I am following the docs on react navigation. And I when I run the code this is the result:
My question is how do I make the center content's width same as the screen.
Also, his is my first time using react native expo after switching from reactJS
Code:
navigator code:
import Login from "./Login";
import Signup from "./Signup";
import {
createAppContainer,
NavigationContainer,
NavigationNavigator,
} from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import Chat from "./Chat";
import Error from "./Error";
/**
* This is the screen stack of the navigation stack.
*/
const screens: any = {
default: { screen: Login },
signup: { screen: Signup },
chat: { screen: Chat },
Error: { screen: Error },
};
const stack: NavigationNavigator<any, any> = createStackNavigator(screens);
const container: NavigationContainer = createAppContainer(stack);
export default container;
App.tsx:
import { StatusBar } from "expo-status-bar";
import React from "react";
import { Alert, StyleSheet, Text, View } from "react-native";
import * as expoAppLoading from "expo-app-loading";
import loadFonts from "./assets/fonts/loader";
import Navigator from "./screens/navigator";
/**
* This is the main app component of the Chill&chat application.
*/
const App: React.FC = () => {
const [loading, setLoading] = React.useState(true);
const style: any = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
text: {
fontFamily: "poppinsBold",
},
});
if (loading) {
return (
<expoAppLoading.default
startAsync={async (): Promise<void> => {
await loadFonts();
}}
onFinish={(): void => {
setLoading(false);
}}
onError={(): void => {
Alert.alert("Error", "Error loading fonts");
}}
/>
);
} else {
return (
<View style={style.container}>
<Navigator />
<StatusBar style="auto" />
</View>
);
}
};
export default App;
You should be able to set the width by adding percentage dimensions to your style sheet for the desired element. This may require you do away with flex layout however, or use flex in a parent instead.
container: {
width:'100%',
},
This should solve for the width problem though.

When importing workspace, in my example it is in shared/components/Header.js, when typing at the end 'export default' it says 'type any' error

I an using yarn workspaces, and i have 3 packages: app, electron app using react, and shared for all the common stuff. When importing shared in the app or electron, it says that error in vscode:
error
i dont know what to do :/ i tried everything. and the files arent ts, but js.
import { View, StyleSheet, Text } from 'react-native';
import Header from 'shared/components/Header';
//const socket = new Socket("192.168.1.146", 8080, "http");
(async () => {
//await socket.connect();
})();
const styles = StyleSheet.create({
screenContainer: {
flex: 1
},
text: {
fontSize: 20,
color: 'cornflowerblue',
marginTop: 50,
alignSelf: 'center'
}
});
const App = () => {
/*useEffect(() => {
if (socket.getSocket() != undefined && socket.getSocket().connected) {
socket.getSocket().disconnect();
}
});*/
return (
<View styles={styles.screenContainer}>
<Header />
<Text style={styles.text}>I'm a React Native component</Text>
</View>
);
};
export default App;
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
header: {
paddingTop: 50,
backgroundColor: 'red'
},
headerText: {
fontSize: 22,
color: 'white',
fontWeight: 'bold',
paddingHorizontal: 10
}
});
const Header = () => {
return (
<View style={styles.header}>
<Text style={styles.headerText}>I'm a shared component.</Text>
</View>
);
};
export default Header;
create fallback.d.ts with content:
declare module '*';
And include it in your tsconfig.json https://www.typescriptlang.org/tsconfig#include (path to d.ts file relative to tsconfig.json path)
{
"include": ["./fallback.d.ts", ...],
...
}
This will allow you to import from js files.
But imho better would be to convert Header.js file to typescript

saveToCameraRoll is not a function

I am trying to send images which are taken using React Native Camera library to Camera Roll.
When the user presses a button the following function gets triggered:
takePicture = async function() {
if (this.camera) {
const options = { quality: 0.5, base64: true }
const data = await this.camera.takePictureAsync(options)
CameraRoll.saveToCameraRoll(data.uri)
}
}
I already know that the app sends pictures to the cache folder because after this code is executed a link to the picture is displayed:
takePicture = async function() {
if (this.camera) {
const options = { quality: 0.5, base64: true }
const data = await this.camera.takePictureAsync(options)
console.log(data.uri)
}
}
The debugger shows the following error:
Possible Unhandled Promise Rejection (id:0)
React Native Camera: TypeError: _reactNative.default.saveToCameraRoll is not a function
The code of the Cam component:
import React, {Component} from 'react';
import {StyleSheet, View} from 'react-native'
import { RNCamera } from 'react-native-camera'
import CameraRoll from 'react-native'
import ActionButton from 'react-native-action-button'
import Icon from 'react-native-vector-icons/Ionicons'
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
button: {
height: 200,
justifyContent: 'flex-end',
alignItems: 'center'
},
actionButtonIcon: {
fontSize: 20,
height: 22,
color: 'white',
},
});
export default class Cam extends Component {
constructor() {
super()
this.takePicture = this.takePicture.bind(this)
}
takePicture = async function() {
if (this.camera) {
const options = { quality: 0.5, base64: true }
const data = await this.camera.takePictureAsync(options)
CameraRoll.saveToCameraRoll(data.uri)
}
}
render() {
return (
<View style={styles.container}>
<RNCamera
ref={ref => {this.camera = ref}}
style={{
flex: 1,
width: '100%',
position: 'relative'
}}
>
</RNCamera>
<ActionButton size={80} useNativeFeedback={false} buttonColor="rgba(231,76,60,1)">
<ActionButton.Item useNativeFeedback={false} buttonColor='#9b59b6' title="Settings" onPress={this.props.switchScreen}>
<Icon name="md-create" style={styles.actionButtonIcon} />
</ActionButton.Item>
<ActionButton.Item useNativeFeedback={false} buttonColor='#1abc9c' title="Start" onPress={this.takePicture}>
<Icon name="md-done-all" style={styles.actionButtonIcon} />
</ActionButton.Item>
</ActionButton>
</View>
)
}
}
Looking at this example of how to use CameraRoll :
import {
View,
Text,
TouchableHighlight,
Modal,
StyleSheet,
Button,
CameraRoll,
Image,
Dimensions,
ScrollView,
} from 'react-native'
You have to replace :
import CameraRoll from 'react-native';
by
import { CameraRoll } from 'react-native';
(I've put it as an answer so it can be accepted and close the question)
In your code, you can mutualise the imports like :
import React, {
Component,
} from 'react';
import {
RNCamera,
} from 'react-native-camera';
import {
CameraRoll,
StyleSheet,
View,
} from 'react-native';
import ActionButton from 'react-native-action-button';
import Icon from 'react-native-vector-icons/Ionicons';

undefined is not an object (evaluating '_this.props.navigator.push')

I'm trying to navigate from Homescreen to another screen(Test).I have 'HomeScreen.js' below. Once I click on the register button, I get the above mentioned error.
I've been at this for a whole day, but can't seem to get a straight forward answer.
The error is on my 'Homescreen.js' (Attached screenshot error)
Screenshot
Error is pointing to: this.props.navigator.push under the _handleRegisterView function.
HomeScreen.js
import React from 'react';
import {
StyleSheet,
Text,
View,
AsyncStorage,
Component,
TouchableHighlight,
AppRegistry
} from 'react-native';
import Test from './Test';
import { StackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'SpeedHack',
};
_handleRegisterView = () => {
this.props.navigator.push({
title: 'Test',
component: Test,
backButtonTitle: 'Back'
})
//alert('Register button Pressed!.');
}
render() {
return (
<View style={styles.container}>
<TouchableHighlight onPress={this._handleRegisterView}>
<Text style={[styles.button, styles.blueButton]}>
Register
</Text></View>
);
}
}
Test.js (Doesn't really do anything interesting, loads an image)
import React from 'react';
import { Component, StyleSheet, Text, View, Image } from 'react-native';
class Test extends React.Component {
render() {
let pic = {
uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
};
return (
<View style={styles.container}>
<Text>Ssup Dude! Want some bananas?</Text>
<Image source = {pic} style = {{width: 300, height: 300}}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
You seem to be confused. In react-navigation in order to push a screen, you do not do this.props.navigator.push, you use this.props.navigation.navigate.

Categories

Resources