Promise rejection when I try to load fonts in expo - react-native

I get a problem with Expo and react-native. When I try to loadAsync font from assets folder I get this error:
[Unhandled Promise rejection: Error: Font not found /data/data/host.exp.exponent/cache/ExperienceData/.../ExponentAsset-5868d2d7f28da04ee373451e87d682f8.ttf]
My code in App.js
import React, { Component } from "react";
import { configureStore } from "./store.js";
import { Provider } from "react-redux";
import { AppLoading, Font } from 'expo';
import MainWrapper from './components/mainWrapper'
const store = configureStore();
export default class App extends Component {
state = {
appReady: false
}
loadAssets = async () => {
await Font.loadAsync({
'Arial': require('./assets/fonts/Arial.ttf')
});
this.setState({appReady: true});
}
componentDidMount() {
this.loadAssets()
}
render() {
return (
<Provider store={store}>
{this.state.appReady ?
<MainWrapper />
:
<AppLoading />
}
</Provider>
);
}
}
and I use
"expo": {
"sdkVersion": "21.0.0"
}
Most of my App.js I took from Expo example with some changes. Do you have any ideas how can I resolve this error?

It was broken .ttf file. I downloaded correct file of font from another source and my problem has been resolved. But what about FontAwesome I will explore this.

Related

expo run:android is stuck at blank white screen

As seen in the above image, after successfully building for android, the standalone app is installed on the device but when opened, before showing the Splash screen, the blank white screen appears.
This is my App.js code
import React, { useState, useEffect, useRef } from "react";
import { NavigationContainer } from "#react-navigation/native";
import StackNavigator from "./StackNavigator";
import { AuthProvider } from "./hooks/useAuth";
import { ActivityIndicator, LogBox, View } from "react-native";
import { Asset } from "expo-asset";
import {
Roboto_100Thin,
Roboto_100Thin_Italic,
Roboto_300Light,
Roboto_300Light_Italic,
useFonts,
} from "#expo-google-fonts/roboto";
import AppLoading from "expo-app-loading";
import * as Font from "expo-font";
import * as encoding from "text-encoding";
LogBox.ignoreAllLogs();
function cacheImages(images) {
return images.map((image) => {
if (typeof image === "string") {
return Image.prefetch(image);
} else {
return Asset.fromModule(image).downloadAsync();
}
});
}
function cacheFonts(fonts) {
return fonts.map((font) => Font.loadAsync(font));
}
export default function App() {
const [ready, setReady] = useState(true);
let [fontsLoaded] = useFonts({
"Roboto-Thin": Roboto_100Thin,
Roboto_100Thin_Italic,
"Roboto-Light": Roboto_300Light,
Roboto_300Light_Italic,
});
async function _loadAssetsAsync() {
const imageAssets = await cacheImages([
require("./ASSETS/Loading_Black.gif"),
require("./ASSETS/icons/like.png"),
require("./ASSETS/icons/like-red.png"),
require("./ASSETS/icons/comment.png"),
require("./ASSETS/icons/share.png"),
require("./ASSETS/CHAT_BGRD-02.jpeg"),
]);
await Promise.all([...imageAssets, fontsLoaded]);
}
return ready && fontsLoaded ? (
<NavigationContainer>
<AuthProvider>
<StackNavigator />
</AuthProvider>
</NavigationContainer>
) : (
<AppLoading
startAsync={_loadAssetsAsync}
onFinish={() => setReady(true)}
onError={(e) => {
console.log(e);
}}
/>
);
}
The app is perfectly running on development mode, production mode, and even tried using
expo start --no-dev --minify
All these are perfectly working fine. But if I try to run the app in standalone mode, this is what's the output is. Appreciate your help :)
I had this happen, I updated android studio, updated android studio's sdk tools: Android emulator, hypervisor, platform tools, etc.
Then I re-made the devices in the Virtual Device Manager and then re-ran "expo start --android" and it worked.

Expo fontello don't load

I'm trying to load a fontello icons in my project, but if I try to load in App.js, it send "false' and the app don't load:
import React, {useState} from "react";
import AppLoading from "expo-app-loading";
import { ThemeProvider } from "styled-components";
import theme from "./src/globalStyles/theme";
import Routes from "./src/routes";
import {
useFonts,
Roboto_400Regular,
Roboto_500Medium,
Roboto_700Bold,
} from "#expo-google-fonts/roboto";
import { Fontello } from "./assets/fonts/fontello.ttf";
export default function App() {
const [fontsLoaded] = useFonts({
Roboto_400Regular,
Roboto_500Medium,
Roboto_700Bold,
Fontello,
});
console.log(fontsLoaded)
if (!fontsLoaded) {
return <AppLoading />;
}
return (
<ThemeProvider theme={theme}>
<Routes />
</ThemeProvider>
);
}
And if I comment the line with Fontello, it load the app but I got the following error:
fontFamily "fontello" is not a system font and has not been loaded through Font.loadAsync.
If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system.
If this is a custom font, be sure to load it with Font.loadAsync.
Install expo-font
expo install expo-font
Create a folder called hooks where you App.js is located.
Inside hooks folder create a file called useFonts.js paste this code
useFonts.js
import * as Font from 'expo-font';
import { Roboto_400Regular } from '#expo-google-fonts/roboto';
const useFonts = async () => {
await Font.loadAsync({
Roboto: Roboto_400Regular,
Fontello: require('../assets/fonts/fontello.ttf'),
// All Other Fonts
});
};
export default useFonts;
Then in your App.js paste this code
import React, { useState } from 'react';
import AppLoading from 'expo-app-loading';
import { ThemeProvider } from 'styled-components';
import theme from './src/globalStyles/theme';
import Routes from './src/routes';
import useFonts from './hooks/useFonts';
export default function App() {
const [IsReady, setIsReady] = useState(false);
const LoadFonts = async () => {
await useFonts();
};
if (!IsReady) {
return (
<AppLoading
startAsync={LoadFonts}
onFinish={() => setIsReady(true)}
onError={(error) => console.log(error)}
/>
);
}
return (
<ThemeProvider theme={theme}>
<Routes />
</ThemeProvider>
);
}
Working Example Works on Android. Some bug in the web version.

Not able to install Native Base in my react prject

Does using expo react native doesn't allow to install native base ?
It is documented in nativebase website. You will have to install expo-font and make some adjustments in App.js. The official documentation link is https://docs.nativebase.io/docs/GetStarted.html#Setup_with_Expo
No, expo doesn't stop you from using any frontend package, because there is a specific way to install native base after installing native-base. Put the following code in your main react-native file
import React, { Component } from 'react';
import { Root } from 'native-base';
import Main from "project directory";
import * as Font from 'expo-font';
import { ActivityIndicator } from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
this.state = { loading: true };
}
async componentDidMount() {
await Font.loadAsync({
Roboto: require('native-base/Fonts/Roboto.ttf'),
Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
});
this.setState({ loading: false });
}
render() {
if (this.state.loading) {
return (
<Root>
<ActivityIndicator />
</Root>
);
} else {
return (
<Root>
<Main/>//Your main Javascript project file.
</Root>
);
}
}
}

console.error: "fontFamily "Roboto_medium" is not a system font and has not been loaded through Font.loadAsync

When using import Native Base (as it comes) I have encountered trouble because of a Font error shown in screen. If you click dismiss it will disappear but the user can't be seeing that every time a Text gets loaded. ¿Is there a correct way to solve the font problem?
This official documentation says to do this:
// At the top of your file
import { Font } from 'expo';
import { Ionicons } from '#expo/vector-icons';
// Later on in your component
async componentDidMount() {
await Font.loadAsync({
'Roboto': require('native-base/Fonts/Roboto.ttf'),
'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
...Ionicons.font,
});
}
but it didn't work. This is my code:
import React, { Component } from 'react';
import { View, } from "react-native";
import { Button, Text } from 'native-base';
export default class MyComponent extends Component {
render() {
return (
<View>
<Button>
<Text>Click me!</Text>
</Button>
</View>
)
}
}
I expect the code to run smoothly but every time it loads the same error:
console.error: "fontFamily "Roboto_medium" is not a system font and has not been loaded through Font.loadAsync.
- If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system.
- If this is a custom font, be sure to load it with Font.loadAsync."
__expoConsoleLog
AppEntry.bundle?platform=android&dev=true&minify=false&hot=false:95014:31
...................
...................
...................
Native Base uses Roboto_Medium as a font for Title and some objects. Roboto_Medium is not a system font.
You can do either two things
Install and Load Roboto_Medium font in your codebase.
Edit existing Native Base core files
1) Install and Load Roboto_Medium font in your codebase
After installing Native Base, run these in terminal expo install expo-font.
After that Open your App.js file, add this two lines,
import * as Font from 'expo-font';
import { Ionicons } from '#expo/vector-icons';
After that include function componentDidMount()
async componentDidMount() {
await Font.loadAsync({
Roboto: require('native-base/Fonts/Roboto.ttf'),
Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
...Ionicons.font,
});
this.setState({ isReady: true });
}
You must call componentDidMount() function. If you are using Class Component, then this can be called using constuctor method
constructor(){
componentDidMount();
}
But, if you are using Functional Method, then you have manually call the componentDidMount() function.
2) Edit existing Native Base core files (Alternative)
You have to edit core Native Base files.
Location of File:
commonColor.js
node_modules\native-base\dist\src\theme\variables \ commonColor.js
material.js
node_modules\native-base\dist\src\theme\variables \ material.js
platform.js
node_modules\native-base\dist\src\theme\variables \ platform.js
In this files, find "Roboto_Medium" and replace it with "Roboto" or any other system default fonts.
But, as we have hardcoded the node_modules, with each update of Native Base, you have to again hard code the values again.
If anyone still has this problem and is using functional components, i solved it like this:
import * as Font from 'expo-font';
useEffect(() => {
(async () => await Font.loadAsync({
Roboto: require('native-base/Fonts/Roboto.ttf'),
Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
}))();
}, [])
For newer Functional Components solved it like this
import { View } from 'react-native';
import { NativeBaseProvider, Text } from 'native-base';
const MyComponent = () => {
return (
<NativeBaseProvider>
<View>
<Text>Example Text</Text>
</View>
</NativeBaseProvider>
)
}
export default MyComponent;
For older Functional Components solved it like this
import { View } from 'react-native';
import { Text } from 'native-base';
import * as Font from 'expo-font';
const MyComponent = () => {
useEffect(() => {
(async () => await Font.loadAsync({
Roboto: require('native-base/Fonts/Roboto.ttf'),
Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
}))();
}, [])
return (
<View>
<Text>Example Text</Text>
</View>
)
}
export default MyComponent;
For Class Components solved it like this
import React, { Component } from 'react';
import { View, } from "react-native";
import { Button, Text } from 'native-base';
import { Font } from 'expo';
import { Ionicons } from '#expo/vector-icons';
export default class MyComponent extends Component {
state = {
loading: true
}
async componentDidMount() {
await Font.loadAsync({
'Roboto': require('native-base/Fonts/Roboto.ttf'),
'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
...Ionicons.font,
})
this.setState({ loading: false })
}
render() {
if (this.state.loading) {
return (
<View></View>
);
}
return (
<View>
<Button>
<Text>Click me!</Text>
</Button>
</View>
)
}
}

How to load "ionicons" font in expo sdk33?

after upgrading to expo sdk 33.0.0, when i build my react native expo app everything is ok but as soon as the app starts the the following error shows up:
fontFamily "ionicons" is not a system font and has not been loaded through Font.loadAsync
before the update i was using the sdk version 32.0.0 and everything was ok.
I tried to add the font as explained here https://docs.expo.io/versions/latest/guides/using-custom-fonts/ in my app.js componentDidMount function:
const Ionicons = require("./fonts/Ionicons.ttf");
...
componentDidMount() {
...
Font.loadAsync({
"Avenir-Book": AvenirBook,
"Avenir-Light": AvenirLight,
"Ionicons": Ionicons,
})
}
...
I also try to change the name in the loadAsync from "Ionicons" to "ionicons" but nothing changed.
The "Ionicons.ttf" inside the fonts folder file was copied from the node_modules/#expo/vector-icons/build/vendor/react-native-vector-icons/Fonts folder
---------EDIT---------
In all my react native expo project src i have not a single reference to Ionicon
Any help is appreciated,
Thanks
To import Ionicons icons do
import { Ionicons } from '#expo/vector-icons';
// use like
<Ionicons name="md-checkmark-circle" size={32} color="green" />
And to import custom fonts, add the path to the font to require.
import { Font } from 'expo';
componentDidMount() {
Font.loadAsync({
'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'),
});
}
import React from 'react';
import { AppLoading } from 'expo';
import { Container, Text } from 'native-base';
import * as Font from 'expo-font';
import { Ionicons } from '#expo/vector-icons'; // here, do a call "ionicons" font
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isReady: false,
};
}
async componentDidMount() {
await Font.loadAsync({
Roboto: require('native-base/Fonts/Roboto.ttf'),
Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
ionicons: Ionicons.font['ionicons'] // and here is what changes so that the font loads
});
this.setState({ isReady: true });
}
render() {
if (!this.state.isReady) {
return <AppLoading />;
}
return (
<Container>
<Text>Open up App.js to start working on your app!</Text>
</Container>
);
}
}
Nativebase
async componentDidMount() {
await Font.loadAsync({
Roboto: require('native-base/Fonts/Roboto.ttf'),
Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
...Ionicons.font,
});
this.setState({ isReady: true });
}
Me
async componentDidMount() {
await Font.loadAsync({
Roboto: require('native-base/Fonts/Roboto.ttf'),
Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
ionicons: Ionicons.font['ionicons'] // here
});
this.setState({ isReady: true });
}