Launch url in default video player on android with react native - react-native

I found this native android code for what I am trying to achieve
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(newVideoPath), "video/mp4");
startActivity(intent);
(Android intent for playing video?)
But I can't figure out how to use apply it in react native with the Linking.sendIntent api, or if that api is even capable of doing it.
I also tried this module, but it failed to build the project with the error method does not override or implement a method from a supertype
I don't want to write a native module for this.

Turns out you can't send data with an intent with the built in sendIntent api, however there's a handy library that's capable of doing that (react-native-send-intent).
So now I am able to achieve what I wanted like so:
import { Linking, Platform } from "react-native";
import SendIntentAndroid from "react-native-send-intent";
export function playVideo(url){
var fn = Platform.select({
android(){
SendIntentAndroid.openAppWithData(
/* "org.videolan.vlc" */null,
"https://www.w3schools.com/html/mov_bbb.mp4",
"video/*"
).then(wasOpened => {});
},
default(){
Linking.openURL(url).catch(err => {});
}
});
fn();
}
Despite the library not offering a function for launching the default app for a url, you can achieve it by passing in null as the packagename, since the function it uses under the hood Intent.setPackage(String packageName), accepts null as a value.

Related

PermissionsAndroid for iOS in React Native

I use this code to get user permission in android
async componentWillMount() {
await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION);
}
How to use this for ios?
This library used only with android , Use Third party library Like :
https://github.com/yonahforst/react-native-permissions

Redux: Is there any smart way to avoid the antipattern of importing store for helper files?

I'm currently build a React Native application using Redux the state management and Firebase Cloud Messaging for my real time communication.
To use FCM in the background on Android you are required to create file called bgMessaging.js.
// #flow
import firebase from 'react-native-firebase';
// Optional flow type
import type { RemoteMessage } from 'react-native-firebase';
export default async (message: RemoteMessage) => {
// handle your message
return Promise.resolve();
}
My problem is that I need to dispatch an action here. The only solution I found for this was to import my store and call store.dispatch(). I've been told this is an anti-pattern and considered bad practice. What else could I do that is not an anti-pattern?
Edit:
Mark Erikson himself was so kind and gave his opinion on this topic. Thanks Mark!
I've also come into the same scenario when writing my application. My approach to my React Native App was to create React Components, but deal with a lot of my data fetching/handling outside of React Components - because I didn't know whether I'd be using React all of the time, but wanted to create re-usable modules for my other Type/JavaScript projects. For example I'd created a few helper files which dealt with various APIs, but when I integrated Redux into my project - I had the same issue. How do I dispatch without re-adding in your store (as I can see this can be considered Anti-Pattern).
Reading into a few articles, there's no real place to suggest that this approach is 'Anti Pattern'. A lot of the time, stores are imported within the React Context (which is doesn't need to be) - this is Anti Pattern. In your use case, I don't really see how that can be Anti Pattern, I certainly came to this conclusion when I was doing the same thing. In my view 'Common' parts of the app should be used by many other parts of the application.
What I'm seeing is that you need to provide a function which has a single arg, typed as RemoteMessage which returns a promise, and you need to provide that function to registerHeadlessTask (wrapped in another function for some reason..)
So what if your bgMessaging file looked like this..
// #flow
import firebase from 'react-native-firebase';
// Optional flow type
import type { RemoteMessage } from 'react-native-firebase';
export default store => {
return async (message: RemoteMessage) => {
// handle your message
store.dispatch();
return Promise.resolve();
}
}
and in your index you did..
import bgMessaging from './src/bgMessaging';
const store = redux.createStore();
const bgMessagingFn = bgMessaging(store);
// Current main application
AppRegistry.registerComponent('ReactNativeFirebaseDemo', () => bootstrap);
// New task registration
AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => bgMessagingFn);

Correct way to use initialize firestore in react-native expo app

Have seen two different ways to initialize firestore in a react-native app and would like to know what the differences between the two are. The method shown in the firestore docs (https://firebase.google.com/docs/firestore/quickstart#initialize) looks like
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
export fs = admin.firestore();
while the "firebase" way (as seen in this expo post: https://forums.expo.io/t/open-when-an-expo-firebase-firestore-platform/4126/29), which is the way I currently use and appears to work, looks like
import * as firebase from 'firebase';
import 'firebase/firestore';//for using firestore functions, see https://stackoverflow.com/a/50684682/8236733
import { firebaseConfig } from './firebase-credentials';//WARN: gitignored, exports object containing firebase (web)app credentials
// Initialize Firebase
// why in separate file? see https://github.com/zeit/next.js/issues/1999 and https://ilikekillnerds.com/2018/02/solving-issue-firebase-app-named-default-already-exists/
// firebase.initializeApp(firebaseConfig);
try {
firebase.initializeApp(firebaseConfig)
/*WARN:
#firebase/firestore:, Firestore (5.0.4):
The behavior for Date objects stored in Firestore is going to change
AND YOUR APP MAY BREAK.
To hide this warning and ensure your app does not break, you need to add the
following code to your app before calling any other Cloud Firestore methods:
const firestore = firebase.firestore();
const settings = {timestampsInSnapshots: true};
firestore.settings(settings);
With this change, timestamps stored in Cloud Firestore will be read back as
Firebase Timestamp objects instead of as system Date objects. So you will also
need to update code expecting a Date to instead expect a Timestamp. For example:
// Old:
const date = snapshot.get('created_at');
// New:
const timestamp = snapshot.get('created_at');
const date = timestamp.toDate();
Please audit all existing usages of Date when you enable the new behavior. In a
future release, the behavior will change to the new behavior, so if you do not
follow these steps, YOUR APP MAY BREAK.
*/
const fsSettings = {/* your settings... */ timestampsInSnapshots: true};
firebase.firestore().settings(fsSettings)
} catch (err) {
// we skip the "already exists" message which is
// not an actual error when we're hot-reloading
if (!/already exists/.test(err.message)) {
console.error('Firebase initialization error', err.stack)
}
}
export const fs = firebase.firestore()
The post linked to is the only instance where I could find someone else doing this, but again it does work for me (can read and write to firestore).
Very new to using firebase/firestore and would like to use the more 'correct' method. Is there any difference between initializing firestore in the app in these separate ways?
Import:
import * as firebase from 'firebase';
import 'firebase/firestore';
Then
const db = firebase.firestore();
https://github.com/invertase/react-native-firebase
This is a JavaScript bridge to the native Firebase SDKs for both iOS and Android therefore Firebase will run on the native thread.
It has a step-by-step instructions for react-native app integration with firebase.
One important thing is that you have to consider about your react-native version and firebase sdk version.
They do the same things though? The first one simply does it by declaring and expo does it by declaring it inline. You can do it however you like, but both of them do the same things

react native share in a single application

In my react-native app, I want to share a text message with a specific application, e.g whatsapp or texting application without having to first land on the dialog with all the social applications.
For instance if I press the share button and whatsapp is called directly.
I tried using react-native-share but it seems to not be working anymore.
You can use Linking, which gives you a general interface to interact with both incoming and outgoing app links.
For example:
import React, { Component } from 'react';
import { Linking, Button } from 'react-native';
export class App extends Component {
render() {
return <Button
onPress={() => {
let url = 'whatsapp://send?text=Hola Mundo';
Linking.openURL(url).then((data) => {
console.log('open whatsapp')
}).catch(() => {
console.log('App not installed')
});
}}
title="Whatsapp"
color="#4FBE3C"/>;
}
}
For Android, the React Native Share module uses the default ACTION_SEND android intent:
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
In order to have a different behavior, you need either write our own RN plugin that would talk to the app you want it to (if such feature is available) or find a similar plugin on npm.
I assume your plugin should do something like this:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);
sendIntent.setPackage("com.whatsapp");

ES6 Proxy not defined in React Native when not in remote debug mode?

I'm wrapping an imported SDK class with a Proxy so that I can eventually catch RequestExceptions, i.e. when there is no network connection to display error popups.
The app is working without issues in remote debugging mode, however, when I disable it the error Can't find Variable: Proxy is thrown. Do I need to import this explicitly somehow? Or is there an alternative method to wrap a class so that I can catch all of its exceptions?
Below is the code for the Proxy wrapper.
import Backend from 'backend-sdk';
import RequestException from 'backend-sdk/src/exceptions/RequestException';
let handler = {
get: (target, name, receiver) => {
try {
return Reflect.get(target, name, receiver);
} catch (e) {
if (e instanceof RequestException) {
console.error(e);
//TODO Add a toast notification for failed API requests
} else {
throw e;
}
}
}
};
export default new Proxy(new Backend(), handler);
Proxy is not pollyfilled in react native by default. It works in chrome debugger because react native uses chrome js engine during debugging see Document on js environment. You may try using Proxy pollyfill.
Note that as of react-native 0.59, react-native on Android now uses a more modern version of JavaScriptCore that includes Proxy support.