How to Debug White Screen Page (No Content Showing) in RN Expo App with No Error Prompts
Asked Answered
A

6

6

I've been building an app in React Native Expo. First, I incorporated Facebook Login simply by copying and pasting the login async code into Login.js and added this.login() to componentWillMount. This worked - With the Facebook login popup showing up as app loads. I was able to log into my FB account with a success message.

However, as soon as I tried to incorporate Firebase, particularly somewhere between transferring code between my Home.js page and the Login.js page, I started getting this white screen to appear on page load.

There are no errors in a terminal; except a message that FacebookAppID and facebookDisplayName do not belong in app.json.

I tried adding a different background color (black) in CSS, which works, but still, there is no content.

Removing FacebookAppID and facebookDisplayName from app.json, which did nothing.

Updating my App Key to the correct one (I was missing the last number).

Restarted the terminal, expo web terminal x code and metro builder several times.

Updated my code so that every file in my Screens directory has { connect } & { login } imports as well as functionMapStateToProps and export default connect statements at bottom.

I tried changing a tab in TabNavigator.js to Login page, and using "Login" as the initialRouteName, but got an error that Login.js isn't a React component.

The first page that should show up before any other is the Facebook login...So it would seem the issue is there.

App.js

import React from 'react';
import Login from './screens/Login';
import reducers from './redux/reducers';
import thunkMiddleware from 'redux-thunk';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
const middleware = applyMiddleware(thunkMiddleware);
const store = createStore(reducers, middleware);

export default class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
     <Login/>
     </Provider>
    );
  }
}

------ end of App.js ------------

Login.js

import React from 'react';
import styles from '../styles'
import RootNavigator from '../navigation/RootNavigator';
import { connect } from 'react-redux';
import { login } from '../redux/actions';
import * as firebase from 'firebase';
import firebaseConfig from '../config/firebase.js';
firebase.initializeApp(firebaseConfig)

import { 
  Text, 
  View,
  TouchableOpacity
} from 'react-native';

class Login extends React.Component 
  state = {}

  componentWillMount() {
    firebase.auth().onAuthStateChanged((user) => {
      if (user != null) {
        this.props.dispatch(login(true))
        console.log("We are authenticated now!" + JSON.stringify(user));
      }
    });
  }

  login = async () => {
    const { type, token } = await Expo.Facebook.logInWithReadPermissionsAsync('YourAppKeyGoesHere', {
        permissions: ['public_profile'],
      });
    if (type === 'success') {
      // Build Firebase credential with the Facebook access token.
      const credential = await firebase.auth.FacebookAuthProvider.credential(token);

      // Sign in with credential from the Facebook user.
      firebase.auth().signInWithCredential(credential).catch((error) => {
        // Handle Errors here.
        Alert.alert("Try Again")
      });
    }
  } 

  render() {
    if(this.props.loggedIn){
      return (
        <RootNavigator/>
      )
    } else {
      return (
        <View style={styles.container}>
          <TouchableOpacity onPress={this.login.bind(this)}>
            <Text>{this.props.loggedIn}</Text>
          </TouchableOpacity>
        </View>
      )      
    }
  }
}

function mapStateToProps(state) {
  return {
    loggedIn: state.loggedIn
  };
}

export default connect(mapStateToProps)(Login);

---------end of Login.js ----------

Home.js

import React from 'react';
import styles from '../styles';
import { connect } from 'react-redux';
import { login } from '../redux/actions';

import { 
  Text, 
  View,
  Alert
} from 'react-native';

class Home extends React.Component {
  state = {}

  componentWillMount() {

  }


  render() {
    return (
     <View>
      <Text>Home</Text>
     </View>
    )
  }
}

function mapStateToProps(state) {
  return {
    loggedIn: state.loggedIn
  };
}

export default connect(mapStateToProps)(Home);

-----end of Home.js ------

redux folder

actions.js

export function login(){
    return function(dispatch){
        dispatch({ type: 'LOGIN', payload: input });
    }
}

----end of actions.js ----

reducers.js

export default reducers = (state = {
    loggedIn: false,
}, action) => {
    switch (action.type) {
        case 'LOGIN': {
            return { ...state, loggedIn: action.payload  }
        }
    }
    return state;
}

------end of reducers.js ------ -----end of redux folder ------

-----navigation folder (react navigation) ------- ---RootNavigator.js---

import React from 'react';
import TabNavigator from './TabNavigator';

import {
    createDrawerNavigator,
    createStackNavigator,
    createBottomTabNavigator,
    createAppContainer,
} from 'react-navigation';

const AppNavigator = createStackNavigator(
  {
    Main: {
      screen: TabNavigator,
    },
  }
);

const AppContainer = createAppContainer(AppNavigator);

export default class RootNavigator extends React.Component {
  render() {
    return <AppContainer/>;
  }
}

----end of RootNavigator.js-----

----TabNavigator.js----

import React from 'react';
import Home from '../screens/Home';
import Profile from '../screens/Profile';
import Matches from '../screens/Matches';


import {
    createDrawerNavigator,
    createStackNavigator,
    createBottomTabNavigator,
    createAppContainer,
    createMaterialTopTabNavigator,
} from 'react-navigation';

export default createBottomTabNavigator(
  {
    Profile: {
      screen: Profile,
      navigationOptions: {
        tabBarLabel: 'Profile',
      },
    },
    Home: {
      screen: Home,
      navigationOptions: {
        tabBarLabel: 'Home',
      }
    },
    Matches: {
      screen: Matches,
      navigationOptions: {
        tabBarLabel: 'Matches',
      },
    },
  },
  {
    navigationOptions: {
      header: null
    },
    tabBarPosition: 'top',
    initialRouteName: 'Home',
    animationEnabled: true,
    swipeEnabled: true,
    tabBarOptions: {
      style: {
        height: 75,
        backgroundColor: 'blue'
      },
    }
  }
);

-----end of TabNavigator----

Amphibolous answered 18/2, 2019 at 3:18 Comment(0)
E
1

Have you tried remote js Debugging? What you can do is, Debugg JS remotely. https://developers.google.com/web/tools/chrome-devtools/remote-debugging/

try to console.log("hi"); when your first component of your app mounts. Try to add it in login page when the login component mounts. That will help you debug unseen error which gets listed in the js debugger. Just check those errors and follow up!

You're good to go!

Euchromosome answered 18/2, 2019 at 5:20 Comment(1)
Thanks Akshay. I'll try this.Amphibolous
S
1

I was also getting splash logo white screen, tired possible solution nothing works out, at last I have remove node_module and yarn.lock. then reinstall and update expo follows cmd:-

$ npm install

$ yarn add expo

$ expo update

try this , works for me.

!!enjoy!!

Simile answered 14/10, 2021 at 5:9 Comment(0)
E
0

As the other answer suggests, once you've done console.log to see the component is actually loading, then for me the issue was I couldn't actually see the content.

My solution was to wrap my content with a <View> to align the content in the middle of the page.

I understand your question is more complex than that, but hopefully, my answer might be able to help other people.

<View
    style={{
        flex: 1,
        alignItems: 'center',
        justifyContent: 'space-around',
    }}>
    <Text>Can you see this?</Text>
</View>
Equality answered 21/9, 2019 at 21:19 Comment(0)
I
0

in my case,

style = {{ borderColor : #fff }}

my mistake is exceptin ' at borderColor value...

fix change to

style = {{ borderColor : '#fff' }}
Inadvertence answered 27/5, 2020 at 11:54 Comment(0)
D
0

Some components such as useState was imported from wrong url, I changed it and imported it from react and fixed it

Democritus answered 26/12, 2021 at 19:22 Comment(0)
C
0

For me it was an issue with how I was using the Stack component in my _layout.tsx files.

My scenario

I had a folder structure like this (simplified for clarity):

app
 _layout.tsx
 (root)
 | _layout.tsx // Note: This was the only file directly in the "(root)" folder
 | (tabs)
 | | _layout.tsx
 | | home.tsx

The relevant part of app/_layout.tsx:

<Stack screenOptions={{ headerShown: false }}>
    <Stack.Screen name="(root)" />
</Stack>

The relevant part of app/(root)/_layout.tsx:

<SafeAreaView>
    <Slot />
</SafeAreaView>

The relevant part of app/(root)/(tabs)/_layout.tsx:

<Stack screenOptions={{ headerShown: false }}>
    <Stack.Screen name="home" />
</Stack>

The relevant part of app/(root)/(tabs)/home.tsx:

export default function Home() {
    Alert.alert('Home loaded')

    return <View style={{ height: 100, width: '100%', backgroundColor: 'green' }} />
}

My issue was that my "Home loaded" alert triggered but my <View /> refused to render.

My solution

I deleted the app/(root)/_layout.tsx file.

<Slot /> and <Stack /> don't seem to mix very well and using <Slot.Screen name="(tabs)" /> wasn't working for me either for some reason.

I then modified app/_layout.tsx so it went from name="(root)" to name="(root)/(tabs)".

<Stack screenOptions={{ headerShown: false }}>
    <Stack.Screen name="(root)/(tabs)" />
</Stack>

Those two changes solved my blank screen issue.

Celestine answered 28/8, 2024 at 7:43 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.