I am trying to implement a Document Picker using Expo v32. The component opens, closes and uploads properly. However, Android's document picker only allows me to choose images.
I have tried specifying the MIME types for files: application/msword, application/vnd.ms-excel for example. But this still doesn't work. I also tried setting { type: "*/*" } in the getDocumentAsync call but with no luck.
import React, { Component } from 'react'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { DocumentPicker } from 'expo';
import { TouchableOpacity, Text } from 'react-native'
import { postDocument } from '../../../actions/deal'
class AddFiles extends Component {
_pickDocument = async () => {
// Get the document from picker and upload with API
let result = await DocumentPicker.getDocumentAsync({});
if(result.type == 'success'){
this.props.postDocument(this.props.dealId, result)
}
}
render(){
return(
<TouchableOpacity onPress={this._pickDocument}>
<Text>
Add Files
</Text>
</TouchableOpacity>
)
}
}
function mapDispatchToProps(dispatch){
return bindActionCreators({ postDocument }, dispatch)
}
export default connect(null, mapDispatchToProps)(AddFiles)
I would expect to see all possible files available for choosing, but I can only pick images.
Any idea on what I'm missing?
So this code actually works but there is one catch:
Expo's Document Picker - by default - does not allow Google Docs, Sheets or Slides to be added.
All of those files which are "disabled" are Google Drive files. Once you convert them to proper .docx or .xls then they will work.
To add google drive files, you need to specify their MIME types:
application/vnd.google-apps.document
application/vnd.google-apps.spreadsheet
application/vnd.google-apps.presentation
All Google Drive Mime types are here: https://developers.google.com/drive/api/v3/mime-types
Related
I've already published an app for IOS and Android.
But the app makes launch time around 5 seconds.
I detect it to make around 5 seconds to load the first screen in Routes
The app.tsx code below:
import React, {useEffect} from 'react';
import configureStore from './Store';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import {Provider} from 'react-redux';
import {PersistGate} from 'redux-persist/es/integration/react';
import {NavigationContainer} from '#react-navigation/native';
import Routes from './configs/Routes';
import {navigationRef} from './services/NavigationService';
import {LocalizationProvider} from './locales/Translation';
import ModalContainer from './modules/ModalGlobal/containers/ModalContainer';
import NetInfoContainer from './containers/NetInfoContainer';
import {
listenNotificationForeground,
requestUserPermission,
} from './services/NotificationService';
import axios from 'axios';
import {removeCurrentSession} from './modules/Setting/service/SettingService';
import {UNAUTHORIZED} from './configs/Constants';
axios.interceptors.response.use(
response => response,
error => {
const {status} = error.response;
if (status === UNAUTHORIZED) {
removeCurrentSession();
}
return Promise.reject(error);
},
); // User for HTTP code difirrent 200 from axios
const App = () => {
useEffect(() => {
let listenBackground: any;
async function _notificationHandle() {
await requestUserPermission();
listenBackground = listenNotificationForeground();
}
_notificationHandle();
return listenBackground;
}, []);
return (
<Provider store={configureStore().store}>
<PersistGate loading={null} persistor={configureStore().persistor}>
<SafeAreaProvider>
<LocalizationProvider> // Locale language
<NetInfoContainer /> // Use to show lost connection
<NavigationContainer ref={navigationRef}>
<Routes />
</NavigationContainer>
<ModalContainer /> // Define global modal to use many routes
</LocalizationProvider>
</SafeAreaProvider>
</PersistGate>
</Provider>
);
};
export default App;
Could I improve anything in this code? Or any way to improve launch time?
Thank you very much!
for android you can eliminate blank screen at the beginning of the project by enabling hermes on app/build.gradle. Hermes convert js code to java code. If you defector your release apk, you can see only java file after enabling hermes and there is a change to reduce the size of your application. the full instruction and documentation see this
You can use react-native-screens to optimize the memory usage and performance of your app, use it as follow (After installing it with yarn add react-native-screens):
Your android/app/src/main/java/<your package name>/MainActivity.java need to look like this:
import android.os.Bundle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null);
}
On your entry file (Mostly App.js), add the following:
import { enableScreens } from 'react-native-screens';
enableScreens(false);
More about it here: Optimize memory usage and performance using react-native-screens
You should also add a splash-screen (if you don't have one) because there will always be a blank screen at the start of 1 second while react-native loads its dependencies. Setting up a splash screen will make this unnoticeable.
i use react-native-splash-screen
I want to create touch id local authentication in react native. I used
npm react-native-touch-id
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
TouchableHighlight
} from 'react-native';
var LocalAuth = require('react-native-touch-id')
var YourComponent = React.createClass({
_pressHandler() {
LocalAuth.authenticate({
reason: 'this is a secure area, please authenticate yourself',
falbackToPasscode: true, // fallback to passcode on cancel
suppressEnterPassword: true // disallow Enter Password fallback
})
.then(success => {
AlertIOS.alert('Authenticated Successfully')
})
.catch(error => {
AlertIOS.alert('Authentication Failed', error.message)
})
},
render() {
return (
<View>
...
<TouchableHighlight onPress={this._pressHandler}>
<Text>
Authenticate with Touch ID / Passcode
</Text>
</TouchableHighlight>
</View>
)
}
})
but it says nothing, i followed this link
https://github.com/ElekenAgency/react-native-touch-id-android
Came here because I've got the same question, but looking at your code I assume you've got lost in mixing libs.
Looking at the line:
var LocalAuth = require('react-native-touch-id')
You're importing LocalAuth which I believe is a part of react-native-local-auth library built on top of react-native-touch-id, while following a tutorial for 3-rd library which is react-native-touch-id-android.
According to their example in the repo, your import should look like this:
import Finger from 'react-native-touch-id-android'
My guess for the reason it's not crashing on you is because you've installed react-native-local-auth somewhere in the process befor trying out react-native-touch-id-android.
Better start all over - go to package.json and remove the above mentioned libraries, then run npm install and then follow the step-by-step guide in the repo you've posted.
I'd be glad if you come back afterwards and report on whether it worked out or not. Good luck.
use this code it worked for me !
import TouchID from 'react-native-touch-id';
TouchID.authenticate('Authentication')
.then(success => {
// Success code
})
.catch(error => {
// Failure code
});
I have a mobile site and I want to make an android browser app where I want to open my site.
I have tried and react-native-browser. Something like..
import {
processColor, // make sure to add processColor to your imports if you want to use hex colors as shown below
} from 'react-native';
// at the top of your file near the other imports
var Browser = require('react-native-browser');
class SampleApp extends Component {
render() {
return (
<View style={{paddingTop:20, flex:1}}>
{Browser.open('https://google.com/')}
</View>
);
}
}
But got no success...
I just want to make a browser that opens my mobile site..
Is there any better way of doing this or if someone has any idea how to use react-native-browser ?
Thanks in advance
Looking at the source code, it seems this browser is only available on iOS.
you must search in this web https://js.coach/react-native?search=browser for example https://github.com/d-a-n/react-native-webbrowser
Why are you trying to look for an external library while there is a WebView Component already integrated with react-native itself?
WebView renders web content in a native view. You can use this
component to navigate back and forth in the web view's history and
configure various properties for the web content.
You can just add a WebView and open up the desired web url.
Example
import React, { Component } from 'react';
import { WebView } from 'react-native';
class MyWeb extends Component {
render() {
return (
<WebView
source={{uri: 'https://github.com/facebook/react-native'}}
style={{marginTop: 20}}
/>
);
}
}
You can use https://www.npmjs.com/package/react-native-webbrowser
Install:
npm i react-native-webbrowser --save
Use:
class SampleApp extends Component {
render() {
return (
<View style={{paddingTop:20, flex:1}}>
<Webbrowser
url="https://your-url.com"
hideHomeButton={true}
hideToolbar={true}
hideAddressBar={true}
hideStatusBar={true}
foregroundColor={'#efefef'}
backgroundColor={'#333'}
/>
</View>
);
}
Set all the hide's props to true to make your app display only the site
i am creating a very simple app for android and iphone/ipad that uses only webview.
How can i store username and password so the user would not have to type them in every single time. Thanks in advance.
import React, { Component } from 'react';
import {
AppRegistry,
WebView
} from 'react-native';
export default class myapp extends Component {
render() {
return (
<WebView
source={{uri: 'https://mysecretappurl.com'}}
/>
);
}
}
AppRegistry.registerComponent('myapp', () => myapp);
Thank you Fabian for a quick response.
I got it solved with injectedJavascript and the data persist even if i close and relaunch the app both on android and ios. I got stuck as at first as tried to go with asyncstorage and reactnativ-webview-bridge but i failed to implement them due to my lack of knowledge.
import React, { Component } from 'react';
import {
AppRegistry,
WebView
} from 'react-native';
export default class myapp extends Component {
render() {
let jsCode = `
var cookie={};
document.cookie.split('; ').forEach(function(i){cookie[i.split('=')[0]]=i.split('=')[1]});
document.querySelector('#email').value=cookie['email'] || '';
document.querySelector('#password').value=cookie['password'] || '';
document.querySelector('#login button').onclick = function(){
document.cookie = 'email='+document.querySelector('#email').value;
document.cookie = 'password='+document.querySelector('#password').value;
};
`;
return (
<WebView
source={{uri: 'https://mysecretappurl.com'}}
injectedJavaScript={jsCode}
/>
);
}
}
AppRegistry.registerComponent('myapp', () => myapp);
I don't know if I understand you correctly:
You are writing a "minified browser" with react native only to show your webpage and you want to prefill the login form on that page?
If it's true you are searching for a possibility to exchange data from your React Native app with your page in the WebView component. Take a look at this tutorial of react-native-webview-bridge .
I would try the following:
Communicate with your Webpage and establish a listener for your login form to pass the credentials to your RN app
Use a module like react-native-simple-store to store the credentials in your RN app
If you start the app the next time check your storage and if the credentials are not empty send them to your webpage via bridge/injected javascript
I am wanting to develop an app where a user can select different gamepacks to install on their android or ios device. A gamepack will consist of:
one or more JSON files
images
sounds
Right now I'm not really concerned if these are transferred individually or in a zip file (though a zip file would certainly be preferred). Of course the device will need to be connected to the Internet to get the current list of gamepacks and to download the ones that the user chooses. Once the gamepacks are downloaded to the phone the user will not need an Internet connection to play the game as they will have all the files.
How do I go about implementing this in my project?
How do I download the files? Would I use the react-native-fetch-blob library and save it in a specific location? This library refers to saving it as "cache" rather than permanently, so I am not sure if this is the correct solution. The specific section I am looking at on the library page is "Use Specific File Path". But because it is cache, should I be looking for something else that is more of a longer term storage? It does say on the page that files will not be deleted so I am a bit confused as to what the difference between permanent storage and cache is in this case.
Once the files are downloaded would I then be able to open images and display them, open sound files and play them, and open the json files and process them?
Check out React Native FS, specifically the documentation on downloadFile:
https://github.com/johanneslumpe/react-native-fs#downloadfileoptions-downloadfileoptions--jobid-number-promise-promisedownloadresult-
Here's a working example:
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View,
Image,
} from 'react-native';
import RNFS from 'react-native-fs';
export default class downloadFile extends Component {
constructor() {
super()
this.state = {
isDone: false,
};
this.onDownloadImagePress = this.onDownloadImagePress.bind(this);
}
onDownloadImagePress() {
RNFS.downloadFile({
fromUrl: 'https://facebook.github.io/react-native/img/header_logo.png',
toFile: `${RNFS.DocumentDirectoryPath}/react-native.png`,
}).promise.then((r) => {
this.setState({ isDone: true })
});
}
render() {
const preview = this.state.isDone ? (<View>
<Image style={{
width: 100,
height: 100,
backgroundColor: 'black',
}}
source={{
uri: `file://${RNFS.DocumentDirectoryPath}/react-native.png`,
scale: 1
}}
/>
<Text>{`file://${RNFS.DocumentDirectoryPath}/react-native.png`}</Text>
</View>
) : null;
return (
<View>
<Text onPress={this.onDownloadImagePress}>Download Image</Text>
{preview}
</View>
);
}
}
AppRegistry.registerComponent('downloadFile', () => downloadFile);
It's important to know that the height and width must be set on the Image