title: Firestore Missing or Insufficient Privileges and React Native
body: <p>I'm new to Firebase and React Native. I am getting a <strong>Missing or Insufficient Privileges</strong> error when I add email authentication to the app and update the Authentication Rules.</p>
  <p>I receive the error when trying to write to Firestore in the componentDidMount function in Screen1.</p>
  <p>I have added the following rules for my app.</p>
  <pre><code>rules_version = '2';
  service cloud.firestore {
    match /databases/{database}/documents {
      match /{document=**} {
         allow read, write: if request.auth != null;
      }
    }
  }
  </code></pre>
  <p>If I change to <code>allow read, write: if true; </code> everything works fine. However, that is not what I need for a production app that I plan on deploying.</p>
  <p>I checked my app by pulling in the current User and it looks like the user is logged in and authenticated.</p>
  <p>And I get the authentication error: [FirebaseError: Missing or insufficient permissions.] when I try to do the following:</p>
  <p>Config.js</p>
  <pre><code>import Firebase from &quot;firebase&quot;;
  
  // Web App Firebase Configuration
  var firebaseConfig = {
      apiKey: &quot;pretendapikeytoprotect&quot;,
      authDomain: &quot;pretendapp.firebaseapp.com&quot;,
      databaseURL: &quot;https://pretendapp.firebaseio.com&quot;,
      projectId: &quot;pretendapp&quot;,
      storageBucket: &quot;pretendapp.appspot.com&quot;,
      messagingSenderId: &quot;messengerSenderIDnumbers&quot;,
      appId: &quot;appIDNumber&quot;,
      measurementId: &quot;measureIDnumberiD&quot;
    };
  
    const app = Firebase.initializeApp(firebaseConfig);
  
    // Initialize Cloud Firestore through firebase
    export const db = app.firestore();
    db.settings({experimentalForceLongPolling: true});
  </code></pre>
  <p>App.js</p>
  <pre><code>/**
   * @format
   * @flow strict-local
   */
  import 'react-native-gesture-handler';
  import React, {Component} from 'react';
  import Providers from './src/navigation';
  
  import {
    Alert,
    I18nManager,
    YellowBox
  } from 'react-native';
  
  //Ignore Warning about Setting a Timer/No known fix at this time.
  YellowBox.ignoreWarnings(['Setting a timer']);
  
  type Props = {};
  
  export default class App extends React.Component&lt;Props, State&gt; {
  
      constructor(props: Props) {
        super(props);
        
      }
  
      componentWillUnmount() {
        //willMountFunctions
      }
  
      componentDidMount() {
      //DidMountFunctions    
      }
  
    render() {
      return (
        &lt;Providers /&gt;
      )
    }
  }
  </code></pre>
  <p>Providers - /src/navigation/index.js</p>
  <pre><code>import React from 'react';
  import { AuthProvider } from './AuthProvider';
  import Routes from './Routes';
  
  export default function Providers()  {
      return (
      &lt;AuthProvider&gt;
        &lt;Routes /&gt;
      &lt;/AuthProvider&gt;
    );
  }
  </code></pre>
  <p>Routes.js</p>
  <pre><code>import React, { useContext, useState, useEffect } from 'react';
  import { NavigationContainer } from '@react-navigation/native';
  import auth from '@react-native-firebase/auth';
  import AuthStack from './AuthStack';
  import HomeStack from './HomeStack';
  import { AuthContext } from './AuthProvider';
  import Loading from '../components/Loading';
  
  export default function Routes() {
  
      const { user, setUser } = useContext(AuthContext);
      const [loading, setLoading] = useState(true);
      const [initializing, setInitializing] = useState(true);
      
      // Handle user state changes
      function onAuthStateChanged(user) {
        setUser(user);
        if (initializing) setInitializing(false);
        setLoading(false);
  
        if (user) {
          console.log('user is logged');
        }
      }
  
      useEffect(() =&gt; {
        const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
        return subscriber; // unsubscribe on unmount
      }, []);
  
      if (loading) {
        return &lt;Loading /&gt;;
      }
  
      return (
        &lt;NavigationContainer&gt;
          {user ? &lt;HomeStack /&gt; : &lt;AuthStack /&gt;}
        &lt;/NavigationContainer&gt;
      );
    }
  
  </code></pre>
  <p>HomeStack.js</p>
  <pre><code>import React  from 'react';
  import { createStackNavigator } from '@react-navigation/stack';
  
  //Import Components
  import HomeScreen from '../screens/HomeScreen';
  import Screen1 from '../screens/Screen1';
  
  const Stack = createStackNavigator();
  
  export default function HomeStack() {
  
    return (
      &lt;Stack.Navigator initialRouteName=&quot;Home&quot;&gt;
          &lt;Stack.Screen name=&quot;Home&quot;
                    component = {HomeScreen}
                    options={{ title: 'Home Screen' }} /&gt;
          &lt;Stack.Screen name=&quot;Screen1&quot; 
                    component={Screen1}
                    options={{ title: 'Screen 1' }}  /&gt;
      &lt;/Stack.Navigator&gt;
    );
  }
  </code></pre>
  <p>Helper file (helpers.js)</p>
  <pre><code>const RNFS = require('react-native-fs');
  import storage from '@react-native-firebase/storage';
  import firestore from '@react-native-firebase/firestore';
  import { db } from '../config';
  import { Platform } from 'react-native';
  import { currentUser } from '../navigation/AuthProvider';
  import auth from '@react-native-firebase/auth';
  
  // removed other functions not relevant to question //
  
   export const WriteSessionData = async (sessionID) =&gt; {
      
        console.log(&quot;Write Session current User Logged in &quot;, currentUser.uid);
        console.log(&quot;Current Session User in Write Session &quot;, auth().currentUser)
  
        const session = db.collection('sessions').doc(sessionID);
        
        await session.set({
          name: '',
          email: '',
          timedate : Date.now(),})
          .then(() =&gt; {
            console.log(&quot;Session Data Added to Database&quot;);
          }).catch((err) =&gt; {
        console.log(&quot;Error in Writing to Database &quot;, &quot;User Logged in as: &quot;, currentUser.uid, err);
      });
  }
    }
  
  </code></pre>
  <p>AuthStack.js</p>
  <pre><code>import React from 'react';
  import { createStackNavigator } from '@react-navigation/stack';
  import SignupScreen from '../screens/SignupScreen';
  import LoginScreen from '../screens/LoginScreen';
  const Stack = createStackNavigator();
  export default function AuthStack() {
    return (
      &lt;Stack.Navigator initialRouteName='Login'&gt;
        &lt;Stack.Screen
          name='Login'
          component={LoginScreen}
          options={{ header: () =&gt; null }}
        /&gt;
        &lt;Stack.Screen name='Signup' component={SignupScreen} /&gt;
      &lt;/Stack.Navigator&gt;
    );
  }
  </code></pre>
  <p>Login Screen</p>
  <pre><code>import React, { useState, useContext } from 'react';
  import { View, Text, StyleSheet, TouchableOpacity, Image } from 'react-native';
  import FormButton from '../components/FormButton';
  import FormInput from '../components/FormInput';
  
  import { AuthContext } from '../navigation/AuthProvider';
  
  export default function LoginScreen({ navigation }) {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
  
    const { login } = useContext(AuthContext);
    return (
  
      &lt;View style={styles.container}&gt;
        &lt;FormInput
          value={email}
          placeholderText='Email'
          onChangeText={userEmail =&gt; setEmail(userEmail)}
          autoCapitalize='none'
          keyboardType='email-address'
          autoCorrect={false}
        /&gt;
        &lt;FormInput
          value={password}
          placeholderText='Password'
          onChangeText={userPassword =&gt; setPassword(userPassword)}
          secureTextEntry={true}
        /&gt;
        &lt;FormButton buttonTitle='Login' onPress={() =&gt; login(email, password)} /&gt;
        &lt;TouchableOpacity
          style={styles.navButton}
          onPress={() =&gt; navigation.navigate('Signup')}
        &gt;
          &lt;Text style={styles.navButtonText}&gt;New user? Join here&lt;/Text&gt;
        &lt;/TouchableOpacity&gt;
      &lt;/View&gt;
  
    );
  }
  
  </code></pre>
  <p>AuthProvider.js</p>
  <pre><code>import React, { createContext, useState } from 'react';
  import auth from '@react-native-firebase/auth';
  
  export const AuthContext = createContext({});
  
  export const AuthProvider = ({ children }) =&gt; {
      const [user, setUser] = useState(null);
  
      return (
        &lt;AuthContext.Provider
          value={{
            user,
            setUser,
            login: async (email, password) =&gt; {
              try {
                await auth().signInWithEmailAndPassword(email, password);
              } catch (e) {
                console.log(e);
              }
            },
            register: async (email, password) =&gt; {
              try {
                await auth().createUserWithEmailAndPassword(email, password);
              } catch (e) {
                console.log(e);
              }
            },
            logout: async () =&gt; {
              try {
                await auth().signOut();
              } catch (e) {
                console.error(e);
              }
            }
          }}
        &gt;
          {children}
        &lt;/AuthContext.Provider&gt;
      );
    };
  
  export const currentUser = auth().currentUser;
  </code></pre>
  <p>HomeScreen.js</p>
  <pre><code>import React, { Component, useContext, useState} from 'react';
  import { Alert, Button, View, Text, Image, PermissionsAndroid, TouchableHighlight, TextInput } from 'react-native';
  import { styles, buttons } from './styles' 
  import auth from '@react-native-firebase/auth';
  import FormButton from '../components/FormButton';
  import { AuthContext } from '../navigation/AuthProvider';
  
  export default function HomeScreen(props) {
  
    const { route, navigation } = props
  
    const { user, logout } = useContext(AuthContext);
  
    function  navigate() {
      console.log(&quot;User Logged In&quot;, auth().currentUser.uid);
      console.log(&quot;Navigating to Screen 1 ....&quot;);
      navigation.navigate('Screen1');
    }
  
    return (
          &lt;View&gt;
            &lt;View style={styles.container}&gt;
            &lt;Text style={styles.description}&gt;You are logged in as {user.email}&lt;/Text&gt;
            &lt;FormButton buttonTitle=&quot;Get Started&quot; onPress={()=&gt; navigate()} /&gt;
            &lt;FormButton buttonTitle='Logout' onPress={() =&gt; logout()} /&gt;
           &lt;/View&gt;
           &lt;/View&gt;
        );
  }
  </code></pre>
  <p>Screen1.js</p>
  <pre><code>import React, { Component } from 'react';
  import { Alert, Button, View, Text, Image, PermissionsAndroid, TouchableHighlight } from 'react-native';
  import { styles } from './styles' 
  import { db } from '../config';
  import { WriteSessionData} from '../utils/helpers';
  import storage from '@react-native-firebase/storage';
  import { currentUser } from '../navigation/AuthProvider';
  import FormButton from '../components/FormButton';
  
  class Screen1 extends Component {
  
    _isMounted = false;
    
      constructor(props) {
          super(props);
         
          this.state = {
            sessionID: '12345' //random id that will be passed down
          };        
        }
  
        componentWillUnmount() {
          clearInterval(this._progressInterval);
          this._isMounted = false;
        }
    
        componentDidMount() { 
  
          this._isMounted = true;
  
  
          console.log(&quot;User ID in Screen 1 componentDidMount&quot;, currentUser.uid);
          WriteSessionData(this.state.sessionID);
  
          if(this._isMounted){
            //do some other commands
          }        
        }
  
  render() {
        return (
          &lt;View&gt;
            &lt;Text style={styles.title}&gt;Screen 1&lt;/Text&gt;
            &lt;Text style={styles.description}&gt;User Email: {currentUser.email} 
            &lt;/Text&gt;
           &lt;/View&gt; 
        );
      }
    }
    
    export default Screen1;
  
  </code></pre>
  <p>I can even return the user's UID in console.log. I can also see the user is logged in through the Firebase Web Console.</p>
  <p>Am I missing adding some privileges in IAM? Is there some response header issue with the React Native libraries or something I should resolve.</p>
  <p>I have the following libraries and versions installed:</p>
  <pre><code>    &quot;@react-native-firebase/app&quot;: &quot;^8.2.0&quot;,
      &quot;@react-native-firebase/auth&quot;: &quot;^8.2.0&quot;,
      &quot;@react-native-firebase/firestore&quot;: &quot;^7.4.3&quot;,
      &quot;@react-native-firebase/storage&quot;: &quot;^7.2.2&quot;,
      &quot;@react-navigation/native&quot;: &quot;^5.6.1&quot;,
      &quot;@react-navigation/stack&quot;: &quot;^5.6.2&quot;,
      &quot;firebase&quot;: &quot;^7.16.0&quot;,
      &quot;react&quot;: &quot;16.11.0&quot;,
      &quot;react-native&quot;: &quot;0.62.2&quot;,
  </code></pre>