React Native expo managed workflow sharing image uri - react-native

I have a screen on my react native expo managed workflow where the image from a previous screen is passed as a prop the relevant screen as props.pic
What I am trying to now do is share that link as a picture to other apps (like whatsapp or sms) or even just share the image link (if it's not possible to share the picture from the uri). This is what I have tried so far but it keeps giving me this error that I do not have to access the provided file from my firebase storage (I do because a simple copy and paste of the same link works fine everywhere else including in the app):
import React, {useState, useEffect} from 'react';
import { View, TouchableOpacity,Text
Image} from 'react-native';
import * as Sharing from 'expo-sharing';
const Details = props =>{
const [i, setI] = useState(props.pic);
const openShareDialogAsync = async () => {
if (Platform.OS === 'web') {
alert(`Uh oh, sharing isn't available on your platform`);
return;
}
if (!(await Sharing.isAvailableAsync())) {
alert(`Uh oh, sharing isn't available on your platform`);
return;
}
await Sharing.shareAsync(images[i]);
};
return (
<View>
<TouchableOpacity onPress={openShareDialogAsync}>
<Text>Share</Text>
</TouchableOpacity>
</View>
)

Related

Expo-notifications background notification reception handling

I am using expo-notifications package in react native (expo) to handle incoming notifications. I am getting notification correctly when the app is in background and foreground - for sending notifications I am using 'expo-server-sdk' package in the backend. I can handle foreground notification reception using addNotificationReceivedListener() function from expo-notification package.For handling background notification reception in the expo documentation (link: - https://docs.expo.dev/versions/latest/sdk/notifications/#handling-incoming-notifications-when-the-app-is-1) they are saying we can use expo-task-manager library to handle it. The code that i have written by referring expo documentation is given below.
...
import * as Notifications from 'expo-notifications';
import * as TaskManager from 'expo-task-manager';
...
//This code is written in root file and outside any react component
const BACKGROUND_NOTIFICATION_TASK = 'BACKGROUND-NOTIFICATION-TASK';
TaskManager.defineTask(
BACKGROUND_NOTIFICATION_TASK,
({ data, error, executionInfo }) =>{
if(error){
console.log('error occurred');
}
if(data){
console.log('data-----',data);
}
})
//This code is written in App.js root component
useEffect(() => {
Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK);
return()=>{
Notifications.unregisterTaskAsync(BACKGROUND_NOTIFICATION_TASK);
}
},[])
Also in the expo documentation. they say that this background task will not work with expo go app. so O executed expo run:android and build the app into my physical android device. Even After doing all this, When a notification arrives this task is not running and I am not getting any output in the console log from the code console.log('data-----',data); neither getting output for the code console.log('error occurred'); which means 'BACKGROUND-NOTIFICATION-TASK' is not getting executed when notification comes when app is in background. Can anyone please tell me what the problem is?
Basically, the only mistake you made was to call
Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK)
inside useEffect which I am guessing is inside a react component, this code must be written outside the react component as you did with TaskManager.defineTask...
Take a look at this simple App.js example for further clarity
import { StyleSheet, View } from "react-native";
import * as Notifications from "expo-notifications";
import * as TaskManager from "expo-task-manager";
const BACKGROUND_NOTIFICATION_TASK = "BACKGROUND-NOTIFICATION-TASK";
TaskManager.defineTask(
BACKGROUND_NOTIFICATION_TASK,
({ data, error, executionInfo }) => {
if (error) {
console.log("error occurred");
}
if (data) {
console.log("data-----", data);
}
}
);
Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK);
export default function App() {
return <View style={styles.container}></View>;
}
const styles = StyleSheet.create({
container: {
flex: 1
},
});
No need for useEfect

React Native Google Fonts - Pass the custom font to the WHOLE app

After a lot of error messages, especially the following one
If this is a custom font, be sure to load it with Font.loadAsync.
I managed to add Google font to a react native app with the following code:
import AppLoading from "expo-app-loading";
import {
useFonts,
Quicksand_300Light,
Quicksand_400Regular,
Quicksand_500Medium,
Quicksand_600SemiBold,
Quicksand_700Bold,
} from "#expo-google-fonts/quicksand";
const screen = () => {
let [fontLoaded] = useFonts({
Quicksand_300Light,
Quicksand_400Regular,
Quicksand_500Medium,
Quicksand_600SemiBold,
Quicksand_700Bold,
});
if (!fontLoaded) {
return <AppLoading />;
} else {
return (
I use react-navigation and at the moment, I need to add this code to every screen.
I tried to add it to app and receive again the same Font.loadAsync message.
a - How can I import the font once for the whole app?
b - How can I have all the Text in the app use that font without adding it to each Text style?

Expo app problem loading especific custon font weights

I have created an react-native/typescript app with expo CLI, this generate some base code, inlcuding hooks/useCachedResources to load any resources or data that we need prior to rendering the app, in my case in this hook I load custom fonts(in particular Inter Display Font). I'm experimenting some problems because the app loads only two weights: regular and medium, If I try to use semi-bold or bold this doesnt work and use the san serif font that comes by default.
Additional data:
The fonts path its ok
Expo app doesn't show any error. I have seen in other questions errors such as fontFamily "MyFontFamily" is not a system font and has not been loaded through Font.loadAsync. This is not the case.
Font family name is in the correct format.
I'm using React Native UI Kitten and I load the fonts as they suggest in Advanced Configuration and change some especific styles.
According to some answers The out of the box support for custom fonts on Android is a little limited in React Native. It does not support font weights other than normal and bold. So I tried setting fontWeight: normal or any of the weights but nothing works.
useCachedResources hook
This come by default with expo init my-app.
import * as Font from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import { useEffect, useState } from 'react';
// Error reporting service
import { logger } from '#utils';
export function useCachedResources(): boolean {
const [isLoadingComplete, setLoadingComplete] = useState(false);
// Load any resources or data that we need prior to rendering the app
useEffect(() => {
async function loadResourcesAndDataAsync() {
try {
await SplashScreen.preventAutoHideAsync();
// Load fonts
await Font.loadAsync({
'inter-display-regular': require('../assets/fonts/InterDisplay-Regular.ttf'),
'inter-display-medium': require('../assets/fonts/InterDisplay-Medium.ttf'),
'inter-display-semibold': require('../assets/fonts/InterDisplay-SemiBold.ttf'),
'inter-display-bold': require('../assets/fonts/InterDisplay-Bold.ttf'),
});
} catch (loadCachedResourcesError) {
logger.log(loadCachedResourcesError);
} finally {
setLoadingComplete(true);
await SplashScreen.hideAsync();
}
}
loadResourcesAndDataAsync();
}, []);
return isLoadingComplete;
}
Consuming the hook in App.tsx
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import useCachedResources from './hooks/useCachedResources';
import Navigation from './navigation';
// again this comes by defautl expo init command
export default function App(): React.ReactElement | null {
const isLoadingComplete = useCachedResources();
if (!isLoadingComplete) {
return null;
}
return (
<SafeAreaProvider>
<Navigation />
<StatusBar />
</SafeAreaProvider>
);
}
mapping.json: specific UI-Kitten configuration to change font style
I can think that the problem comes from here but the thing is, if there was a problem loading the fonts, either expo would have already thrown an error or the other fonts weights(regular/medium) would not load.
{
"strict": {
"text-font-family": "inter-display-regular",
"text-heading-1-font-size": 32,
"text-heading-1-font-weight": "normal",
"text-heading-1-font-family": "inter-display-medium",
"text-paragraph-1-font-size": 16,
"text-paragraph-1-font-weight": "normal",
"text-paragraph-1-font-family": "$text-font-family",
}
}
The problem
I have no idea if the problem comes from expo, ui kitten or if inter font can't be loaded by react native by some other reason.
In your useCachedResources try to remove 'await' keyword from SplashScreen method's:
SplashScreen.preventAutoHideAsync();
SplashScreen.hideAsync();

How to open other mobile apps on press in React Native?

I am looking for an easy way to open apps, Facebook and Instagram specifically, on a button press from my React Native app. It should also check if the app is installed on the device first, and open the app store if it isn't. It needs to work on both iOS and Android. I am a beginner so if you can post an example it would help.
You can use Linking module of react-native to open other mobile apps.
import { Linking } from "react-native";
const APP_ID = //ID of app need to open in play store
const appDeepLinkURL = //Most of the mobile app provide it
Linking.openURL(appDeepLinkURL).catch(err => {
Linking.openURL(
`market://details?id=${APP_ID}`
).catch(err => Linking.openURL(
`http://play.google.com/store/apps/details?id=${APP_ID}`
).catch(err => console.error("An error occurred", err)););
});
Similarly, you can do for the iOS,
you can refer to the official doc here.
use react-native Linking Component
import {
TouchableOpacity,
Text,
Linking,
} from 'react-native';
<TouchableOpacity onPress={() => { Linking.openURL('sms:' + {contactNumber}
+ '?body=Hi'); }}>
<Text> Open Message App </Text>
</TouchableOpacity>

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");