Firebase Cloud Firestore数据库与React Native应用程序的集成

Firebase Cloud Firestore数据库与React Native应用程序的集成

React Native Cloud Firestore

这是我们的第二篇文章 反应原生 Firebase 系列,在这个例子中我们将看到什么是Firebase Cloud Firestore数据库? 以及如何将 Cloud Firestore 数据库集成到 React Native 应用程序中? 在此示例中,我们将了解如何创建、更新、读取和删除记录。 我们还将了解如何订阅实时更改并在嵌套集合中创建记录。

让我们从 Firebase Cloud Firestore 数据库开始。

推荐:如何在Ubuntu Linux中安装Firefox

Firebase 云 Firestore

Firestore 是一个灵活、可扩展的 NoSQL 云数据库,用于存储和同步数据。 它通过实时侦听器使您的数据在客户端应用程序之间保持同步,并提供离线支持,以便您可以构建无论网络延迟或互联网连接如何都能正常工作的响应式应用程序。

YouTube video

Cloud Firestore 是一个灵活、可扩展的数据库,适用于 Firebase 和 Google Cloud 的移动、Web 和服务器开发。 与 Firebase 实时数据库一样,它通过实时侦听器使您的数据在客户端应用程序之间保持同步,并为移动和 Web 提供离线支持,以便您可以构建不受网络延迟或互联网连接影响的响应式应用程序。 Cloud Firestore 还提供与其他 Firebase 和 Google Cloud 产品(包括 Cloud Functions)的无缝集成。

Cloud Firebase 与实时数据库

Firebase 提供两种基于云、客户端可访问的数据库解决方案,支持实时数据同步:

  • 云Firestore 这是用于移动应用程序开发的最新数据库。 它以实时数据库的成功为基础,采用了新的、更直观的数据模型。 Cloud Firestore 还具有比实时数据库更丰富、更快的查询和可扩展性。
  • 实时数据库 是Firebase的原始数据库。 对于需要跨客户端实时同步状态的移动应用程序来说,这是一种高效、低延迟的解决方案。

根据您的要求,您可以选择您想要使用的任何内容,但根据我的经验,Cloud Firestore 包含实时数据库的所有功能,并且还有很多更新的内容,因此我的建议是使用 Cloud Firestore 而不是实时数据库。

收藏品和文件

与所有其他 NoSQL 数据库一样,Cloud Firestore 将数据存储在“文档”中,“文档”中包含“集合”,并且文档也可以包含集合。 例如,我们可以将用户文档列表存储在“用户”集合中,并且单个用户文档还可以包含与该用户相关的订单集合。

我们将使用 反应原生 Firebase 对于这个例子,它非常容易集成库并提供很多功能。 导入此库后,您可以使用以下方式获取任何集合的引用

const usersCollection = firestore().collection('Users');

或使用任何文档的参考

const usersCollection = firestore().collection('Users').doc('docId');

文档可以包含不同类型的数据,包括标量值(字符串、布尔值、数字)、数组(列表)和对象(映射)以及特定的 Cloud Firestore 数据,例如 时间戳, 地理点, 斑点 和更多。

要详细了解 Firebase Cloud Firestore,您可以访问 反应原生 Firebase。

示例说明

在此示例中,我们涵盖了使用 Firebase 数据库时所需的几乎所有数据库操作。 我们在这个例子中涵盖了嵌套集合和实时订阅的所有 CRUD 操作,并在单独的屏幕上执行所有操作,以便您可以轻松理解代码。 现在让我们看看设置和代码。

制作 React Native 应用程序

React Native 入门将帮助您更多地了解如何制作 React Native 项目。 我们将使用 React Native 命令行界面来制作我们的 React Native 应用程序。

如果您之前安装了全局的react-native-cli软件包,请将其删除,因为它可能会导致意外问题:

npm uninstall -g react-native-cli @react-native-community/cli

运行以下命令创建一个新的 React Native 项目

npx react-native init ProjectName

如果你想使用特定的 React Native 版本启动一个新项目,你可以使用 –version 参数:

npx react-native init ProjectName --version X.XX.X

注意如果上述命令失败,您可能使用的是旧版本 react-native 或者 react-native-cli 在您的电脑上全局安装。 尝试卸载 cli 并使用 npx 运行 cli。

这将在项目目录中创建一个带有名为 App.js 的索引文件的项目结构。

Firebase SDK 集成

要从任何 React Native Firebase 示例开始,您需要将 Firebase 集成到您的应用程序中,我专门为此详细制作了一篇单独的文章,您将在其中看到在 Android 版 React Native 应用程序中添加 Firebase 的点对点过程,以及iOS 两者都有。

请访问如何在 Android 和 iOS 应用程序中集成 Firebase,然后返回执行下一步。

完成 Firebase 集成后,您可以安装更多依赖项。

安装依赖项

要安装依赖项,请打开终端并使用以下命令跳转到您的项目

cd ProjectName

对于 React Native Firebase,我们需要安装和设置应用程序模块

npm install @react-native-firebase/app --save

现在安装 firestore 模块

npm install @react-native-firebase/firestore --save

这对于 Firestore 来说已经足够了,但在这个示例中,我们还将使用 React 导航,因为我们将切换屏幕,因此还要安装以下 React-navigation 依赖项

npm install @react-navigation/native --save

其他用于反应导航的支持库

npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view --save
npm install @react-navigation/stack --save

此命令会将所有依赖项复制到您的 node_module 目录中。 –save 是可选的,它只是更新 package.json 文件中的依赖项。

CocoaPods 安装

React Native 0.60 更新后,他们引入了自动链接,因此我们不需要链接库,但对于 iOS,我们需要安装 pod。 因此要安装 pod,请使用

cd ios/ && pod install --repo-update && cd ..

Cloud Firestore 数据库设置

在进入代码之前,您需要设置 Firestore 数据库,为此,请打开 Firebase 控制台并从左侧菜单中选择 Cloud Firestore

React_native_firebase_cloud_firestore_setup1
单击“创建数据库”,您将看到选择安全规则的选项。 这些规则将帮助您保护数据库。 有关安全规则的更多信息,您可以查看 这。 现在,您可以选择“在测试模式下启动”选项,然后单击“下一步”,然后选择最近的 Cloud Firebase 位置以获得更好的性能。
React_native_firebase_cloud_firestore_setup2
React_native_firebase_cloud_firestore_setup3

现在您可以看到创建集合的选项,单击“开始集合”并使用一些初始数据创建一个新集合。

如果一切顺利,那么您可以看到您的收藏以及其中的初始文档。 请注意,我们删除任何集合的所有文档,然后集合将自动删除。

React Native Cloud Firestore 的项目结构

请创建以下项目结构并复制下面给出的代码。

react_native_firebase_cloud_firestore_struct

你可以看到

  1. 应用程序.js 包含主要导航
  2. 我的按钮.js自定义按钮
  3. Mytext.js自定义文本
  4. Mytextinput.js自定义文本输入
  5. 主屏.js,将有不同的选项来打开不同的屏幕
  6. 注册用户.js在 Firebase 中添加记录
  7. 更新用户.js,更新 Firebase 中的记录
  8. 查看所有用户.js列出集合中的所有记录
  9. 查看用户.js查看与任何文档相关的所有数据
  10. 删除用户.js删除任何记录
  11. RealTimeAddUpdateUser.js,实时添加和查看数据
  12. AddOrderSummary.js在任何文档中添加嵌套记录(文档中的集合)

集成 Firebase Cloud Firestore 数据库的代码

请在任何代码编辑器中打开 App.js 并将代码替换为以下代码

应用程序.js

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db

import 'react-native-gesture-handler';

import * as React from 'react';

import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';

import HomeScreen from './pages/HomeScreen';
import RegisterUser from './pages/RegisterUser';
import UpdateUser from './pages/UpdateUser';
import ViewAllUser from './pages/ViewAllUser';
import ViewUser from './pages/ViewUser';
import DeleteUser from './pages/DeleteUser';
import RealTimeAddUpdateUser from './pages/RealTimeAddUpdateUser';
import AddOrderSummary from './pages/AddOrderSummary';

const Stack = createStackNavigator();

const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="HomeScreen"
        screenOptions={{
          headerStyle: {
            backgroundColor: '#03A89E', //Set Header color
          },
          headerTintColor: '#fff', //Set Header text color
          headerTitleStyle: {
            fontWeight: 'bold', //Set Header text style
          },
        }}>
        <Stack.Screen
          name="HomeScreen"
          component={HomeScreen}
          options={{title: 'Home'}}
        />
        <Stack.Screen
          name="RegisterUser"
          component={RegisterUser}
          options={{title: 'Register'}}
        />
        <Stack.Screen
          name="UpdateUser"
          component={UpdateUser}
          options={{title: 'Update'}}
        />
        <Stack.Screen
          name="ViewAllUser"
          component={ViewAllUser}
          options={{title: 'View All'}}
        />
        <Stack.Screen
          name="ViewUser"
          component={ViewUser}
          options={{title: 'View'}}
        />
        <Stack.Screen
          name="DeleteUser"
          component={DeleteUser}
          options={{title: 'Delete'}}
        />
        <Stack.Screen
          name="RealTimeAddUpdateUser"
          component={RealTimeAddUpdateUser}
          options={{title: 'Real Time Updates'}}
        />
        <Stack.Screen
          name="AddOrderSummary"
          component={AddOrderSummary}
          options={{title: 'Add Order Summary'}}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default App;

页面/组件/Mybutton.js

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db
/*Custom Button*/
import React from 'react';
import {TouchableOpacity, Text, StyleSheet} from 'react-native';

const Mybutton = (props) => {
  return (
    <TouchableOpacity
      style={styles.button}
      onPress={props.customClick}>
      <Text style={styles.text}>{props.title}</Text>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  button: {
    alignItems: 'center',
    backgroundColor: '#03A89E',
    color: '#ffffff',
    padding: 10,
    height: 40,
    marginVertical: 10,
  },
  text: {
    color: '#ffffff',
  },
});

export default Mybutton;

页面/组件/Mytext.js

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db
/*Custom Text*/
import React from 'react';
import {Text, StyleSheet} from 'react-native';

const Mytext = (props) => {
  return <Text style={styles.text}>{props.text}</Text>;
};

const styles = StyleSheet.create({
  text: {
    color: '#111825',
    fontSize: 18,
    marginTop: 16,
  },
});

export default Mytext;

页面/组件/Mytextinput.js

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db
/*Custom TextInput*/
import React from 'react';
import {View, TextInput} from 'react-native';

const Mytextinput = (props) => {
  return (
    <View
      style={{
        marginTop: 10,
        borderColor: '#03A89E',
        borderWidth: 1,
      }}>
      <TextInput
        underlineColorAndroid="transparent"
        placeholder={props.placeholder}
        placeholderTextColor="#03A89E"
        keyboardType={props.keyboardType}
        onChangeText={props.onChangeText}
        returnKeyType={props.returnKeyType}
        numberOfLines={props.numberOfLines}
        multiline={props.multiline}
        onSubmitEditing={props.onSubmitEditing}
        style={props.style}
        blurOnSubmit={false}
        value={props.value}
      />
    </View>
  );
};

export default Mytextinput;

页面/HomeScreen.js

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db

import React from 'react';
import {View} from 'react-native';
import Mybutton from './components/Mybutton';
import Mytext from './components/Mytext';

const HomeScreen = (props) => {
  return (
    <View
      style={{
        flex: 1,
        backgroundColor: 'white',
        flexDirection: 'column',
        paddingHorizontal: 35,
      }}>
      <Mytext text="Firebase Cloud Firestore Database Example" />
      <Mybutton
        title="Register (Add a Document)"
        customClick={
          () => props.navigation.navigate('RegisterUser')
        }
      />
      <Mybutton
        title="Update (Update any Field of Document)"
        customClick={
          () => props.navigation.navigate('UpdateUser')
        }
      />
      <Mybutton
        title="View (View a Single Document Record)"
        customClick={
          () => props.navigation.navigate('ViewUser')
        }
      />
      <Mybutton
        title="View All (View All Document Records)"
        customClick={
          () => props.navigation.navigate('ViewAllUser')
        }
      />
      <Mybutton
        title="Delete (Remove a Document/Field)"
        customClick={
          () => props.navigation.navigate('DeleteUser')
        }
      />
      <Mybutton
        title="Real Time Updates"
        customClick={
          () => props.navigation.navigate('RealTimeAddUpdateUser')
        }
      />
      <Mybutton
        title="Add Collection Under Document"
        customClick={
          () => props.navigation.navigate('AddOrderSummary')
        }
      />
    </View>
  );
};

export default HomeScreen;

页面/RegisterUser.js

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db

import React, {useState} from 'react';
import {View, ScrollView, KeyboardAvoidingView, Alert} from 'react-native';
import Mytextinput from './components/Mytextinput';
import Mybutton from './components/Mybutton';
import firestore from '@react-native-firebase/firestore';

const RegisterUser = (props) => {
  let (userName, setUserName) = useState('');
  let (userContact, setUserContact) = useState('');
  let (userAddress, setUserAddress) = useState('');

  handleRegistration = () => {
    if (userName && userContact && userAddress) {
      /*
        "add()" method adds the new document with a random unique ID
        If you'd like to specify your own ID then use "set()" method
        firestore()
          .collection('Users')
          .doc('101')
          .set({
            name: userName,
            contact: userContact,
            address: userAddress,
          })
        .then(() => {
          console.log('User added!');
        });
      */
      firestore()
        .collection('Users')
        .add({
          name: userName,
          contact: userContact,
          address: userAddress,
        })
        .then(() => {
          Alert.alert(
            'Success',
            'You are Registered Successfully',
            (
              {
                text: 'Ok',
                onPress:
                  () => props.navigation.navigate('HomeScreen'),
              },
            ),
            {cancelable: false},
          );
        })
        .catch((error) => {
          Alert.alert(
            'Exception',
            error,
            (
              {
                text: 'Ok',
                onPress:
                  () => props.navigation.navigate('HomeScreen'),
              },
            ),
            {cancelable: false},
          );
        });

      /*
        You can also add the data using set instead of push
        but in that case you have to provide the user id by
        your own as NoSql DBs have no concept of auto increment
      */
      /*
        firebase.database()
          .ref("users/<You custome key for the User>")
          .set({
            name: userName,
            contact: userContact,
            address: userAddress
          }).then(()=>{
          Alert.alert(
            'Success','You are Registered Successfully',
            ({
              text: 'Ok',
              onPress:
              () => props.navigation.navigate('HomeScreen')}
            ),{ cancelable: false });
      });*/
    } else {
      alert('Please fill all the details');
    }
  };

  return (
    <View
      style={{
        backgroundColor: 'white',
        flex: 1,
        paddingHorizontal: 35
      }}>
      <ScrollView keyboardShouldPersistTaps="handled">
        <KeyboardAvoidingView
          behavior="padding"
          style={{flex: 1, justifyContent: 'space-between'}}>
          <Mytextinput
            placeholder="Enter Name"
            onChangeText={
              (userName) => setUserName(userName)
            }
            style={{padding: 10}}
          />
          <Mytextinput
            placeholder="Enter Contact No"
            onChangeText={
              (userContact) => setUserContact(userContact)
            }
            maxLength={10}
            keyboardType="numeric"
            style={{padding: 10}}
          />
          <Mytextinput
            placeholder="Enter Address"
            onChangeText={
              (userAddress) => setUserAddress(userAddress)
            }
            maxLength={225}
            numberOfLines={5}
            multiline={true}
            style={{textAlignVertical: 'top', padding: 10}}
          />
          <Mybutton
            title="Submit"
            customClick={handleRegistration}
          />
        </KeyboardAvoidingView>
      </ScrollView>
    </View>
  );
};

export default RegisterUser;

页面/UpdateUser.js

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db

import React, {useState} from 'react';
import {
  View,
  ScrollView,
  KeyboardAvoidingView,
  Alert
} from 'react-native';
import Mytextinput from './components/Mytextinput';
import Mybutton from './components/Mybutton';
import firestore from '@react-native-firebase/firestore';

const UpdateUser = (props) => {
  let (userId, setUserId) = useState('');
  let (userName, setUserName) = useState('');
  let (userContact, setUserContact) = useState('');
  let (userAddress, setUserAddress) = useState('');

  const searchUser = () => {
    if (userId) {
      firestore()
        .collection('Users')
        .doc(userId)
        .get()
        .then((documentSnapshot) => {
          /*
            A DocumentSnapshot belongs to a specific document,
            With snapshot you can view a documents data,
            metadata and whether a document actually exists.
          */
          if (documentSnapshot.exists) {
            setUserName(documentSnapshot.data().name);
            setUserContact(documentSnapshot.data().contact);
            setUserAddress(documentSnapshot.data().address);
          } else {
            setUserName('');
            setUserContact('');
            setUserAddress('');
          }
        });
    }
  };

  const updateUser = () => {
    if (userId && userName && userContact && userAddress) {
      /*
        Please note update is not just for the update in firebase,
        while updating if record not found in firebase then
        it will create one, update Method also provides support for
        updating deeply nested values via dot-notation
        .update({ 'details.address.zipcode': 452012 })
      */

      firestore()
        .collection('Users')
        .doc(userId)
        .update({
          name: userName,
          contact: userContact,
          address: userAddress
        })
        .then(() => {
          Alert.alert(
            'Success',
            'Updated Successfully',
            (
              {
                text: 'Ok',
                onPress:
                  () => props.navigation.navigate('HomeScreen')
              },
            ),
            {cancelable: false},
          );
        })
        .catch((error) => {
          Alert.alert(
            'Exception',
            error,
            (
              {
                text: 'Ok',
                onPress:
                  () => props.navigation.navigate('HomeScreen'),
              },
            ),
            {cancelable: false},
          );
        });
    } else {
      alert('Please fill all fields');
    }
  };

  return (
    <View
      style={{
        backgroundColor: 'white',
        flex: 1,
        paddingHorizontal: 35
      }}>
      <ScrollView keyboardShouldPersistTaps="handled">
        <KeyboardAvoidingView
          behavior="padding"
          style={{flex: 1, justifyContent: 'space-between'}}>
          <Mytextinput
            placeholder="Enter User Id"
            style={{padding: 10}}
            value={userId}
            onChangeText={(userId) => setUserId(userId)}
          />
          <Mybutton title="Search User" customClick={searchUser} />
          <Mytextinput
            placeholder="Enter Name"
            value={userName}
            style={{padding: 10}}
            onChangeText={
              (userName) => setUserName(userName)
            }
          />
          <Mytextinput
            placeholder="Enter Contact No"
            value={'' + userContact}
            onChangeText={
              (userContact) => setUserContact(userContact)
            }
            maxLength={10}
            style={{padding: 10}}
            keyboardType="numeric"
          />
          <Mytextinput
            value={userAddress}
            placeholder="Enter Address"
            onChangeText={
              (userAddress) => setUserAddress(userAddress)
            }
            maxLength={225}
            numberOfLines={5}
            multiline={true}
            style={{textAlignVertical: 'top', padding: 10}}
          />
          <Mybutton title="Update User" customClick={updateUser} />
        </KeyboardAvoidingView>
      </ScrollView>
    </View>
  );
};

export default UpdateUser;

页面/ViewAllUser.js

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db

import React, {useState, useEffect} from 'react';
import {FlatList, Text, View} from 'react-native';
import firestore from '@react-native-firebase/firestore';

const ViewAllUser = () => {
  let (listData, setListData) = useState(());

  /*
    You can use different filters, limitar, start-end boundaries
    and can also order the results
    firestore()
        .collection('Users')
        // Filter results
        .where('age', '>=', 18)
        .where('languages', 'in', ('en', 'fr'))
        // Limit results
        .limit(20)
        // Order results
        .orderBy('age', 'desc')
        // Pagination using startAt, endAt, startAfter, endBefore
        .startAt(18)
        .endAt(30)
        .get()
        .then(querySnapshot => {});
  */

  useEffect(() => {
    firestore()
      .collection('Users')
      .get()
      .then((querySnapshot) => {
        /*
            A QuerySnapshot allows you to inspect the collection,
            such as how many documents exist within it,
            access to the documents within the collection,
            any changes since the last query and more.
        */
        let temp = ();
        console.log('Total users: ', querySnapshot.size);
        querySnapshot.forEach((documentSnapshot) => {
          console.log('user Id: ', documentSnapshot.id);
          /*
            A DocumentSnapshot belongs to a specific document,
            With snapshot you can view a documents data,
            metadata and whether a document actually exists.
          */
          let userDetails = {};
          // Document fields
          userDetails = documentSnapshot.data();
          // All the document related data
          userDetails('id') = documentSnapshot.id;
          temp.push(userDetails);
          setListData(temp);
        });
      });
  }, ());

  const itemSeparatorView = () => {
    return (
      <View
        style={{
          height: 0.2,
          width: '100%',
          backgroundColor: '#808080'
        }} />
    );
  };

  let itemView = ({item}) => {
    return (
      <View
        key={item.name}
        style={{
          backgroundColor: 'white',
          padding: 20
        }}>
        <Text>Doc Id: {item.id}</Text>
        <Text>Name: {item.name}</Text>
        <Text>Contact: {item.contact}</Text>
        <Text>Address: {item.address}</Text>
      </View>
    );
  };

  return (
    <View>
      <FlatList
        data={listData}
        ItemSeparatorComponent={itemSeparatorView}
        keyExtractor={(item, index) => index.toString()}
        renderItem={itemView}
      />
    </View>
  );
};

export default ViewAllUser;

页面/ViewUser.js

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db

import React, {useState} from 'react';
import {Text, View} from 'react-native';
import Mytextinput from './components/Mytextinput';
import Mybutton from './components/Mybutton';
import firestore from '@react-native-firebase/firestore';

const ViewUser = () => {
  let (userId, setUserId) = useState('');
  let (userData, setUserData) = useState({});

  const searchUser = () => {
    if (userId) {
      firestore()
        .collection('Users')
        .doc(userId)
        .get()
        .then((documentSnapshot) => {
          /*
            A DocumentSnapshot belongs to a specific document,
            With snapshot you can view a documents data,
            metadata and whether a document actually exists.
          */
          let userDetails = {};
          // Document fields
          userDetails = documentSnapshot.data();
          // All the document related data
          userDetails('id') = documentSnapshot.id;
          setUserData(userDetails);
        });
    }
  };

  return (
    <View style={{paddingHorizontal: 35}}>
      <Mytextinput
        placeholder="Enter User Id"
        onChangeText={(userId) => setUserId(userId)}
        value={userId}
        style={{padding: 10}}
      />
      <Mybutton title="Search User" customClick={searchUser} />
      <View style={{marginTop: 10}}>
        <Text>
          User Id: {userData ? userData.id : ''}
        </Text>
        <Text>
          User Name: {userData ? userData.name : ''}
        </Text>
        <Text>
          User Contact: {userData ? userData.contact : ''}
        </Text>
        <Text>
          User Address: {userData ? userData.address : ''}
        </Text>
      </View>
    </View>
  );
};

export default ViewUser;

页面/DeleteUser.js

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db

import React, {useState} from 'react';
import {View, Alert} from 'react-native';
import Mytextinput from './components/Mytextinput';
import Mybutton from './components/Mybutton';
import firestore from '@react-native-firebase/firestore';

const DeleteUser = (props) => {
  let (userId, setUserId) = useState('');

  const deleteUser = () => {
    if (userId) {
      /* "delete()" method will delete the whole document
        If you want to delete any field from the document
        then you can use "FieldValue"
        Ref: https://rnfirebase.io/reference/firestore/fieldvalue
        firestore().collection('Users').doc('101')
        .update({
          age: firestore.FieldValue.delete(),
        });
      */
      firestore()
        .collection('Users')
        .doc(userId)
        .delete()
        .then(() => {
          Alert.alert(
            'Success',
            'Deleted Successfully',
            (
              {
                text: 'Ok',
                onPress:
                  () => props.navigation.navigate('HomeScreen')
              },
            ),
            {cancelable: false},
          );
        })
        .catch((error) => {
          Alert.alert(
            'Exception',
            error,
            (
              {
                text: 'Ok',
                onPress:
                  () => props.navigation.navigate('HomeScreen')
              },
            ),
            {cancelable: false},
          );
        });
    } else {
      alert('Please Enter ID');
    }
  };

  return (
    <View
      style={{
        backgroundColor: 'white',
        flex: 1,
        paddingHorizontal: 35
      }}>
      <Mytextinput
        placeholder="Enter User Id"
        onChangeText={(userId) => setUserId(userId)}
        style={{padding: 10}}
      />
      <Mybutton title="Delete User" customClick={deleteUser} />
    </View>
  );
};

export default DeleteUser;

页面/RealTimeAddUpdateUser.js

在此屏幕中,您将有一个添加记录的输入,并且可以在下面的列表中实时看到添加的记录。

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db

import React, {useState, useEffect} from 'react';
import {
  SafeAreaView,
  StyleSheet,
  View,
  Text,
  ScrollView,
  TextInput,
} from 'react-native';

import Mybutton from './components/Mybutton';
import firestore from '@react-native-firebase/firestore';

const RealTimeAddUpdateUser = () => {
  let (listData, setListData) = useState(());
  let (inputDoc, setInputDoc) = useState('');

  useEffect(() => {
    const subscriber = firestore()
      .collection('Users')
      .onSnapshot(
        (querySnapshot) => {
          /*
            A QuerySnapshot allows you to inspect the collection,
            such as how many documents exist within it,
            access to the documents within the collection,
            any changes since the last query and more.
          */
          let temp = ();
          console.log('Total users: ', querySnapshot.size);
          querySnapshot.forEach((documentSnapshot) => {
            console.log('user Id: ', documentSnapshot.id);
            /*
              A DocumentSnapshot belongs to a specific document,
              With snapshot you can view a documents data,
              metadata and whether a document actually exists.
            */
            let userDetails = {};
            // Document fields
            userDetails = documentSnapshot.data();
            // All the document related data
            userDetails('id') = documentSnapshot.id;
            temp.push(userDetails);
          });
          setListData(temp);
        },
        (error) => {
          console.log('error', error);
        },
      );

    // Stop listening for updates when no longer required
    return () => subscriber();
  }, ());

  const onDocSubmit = () => {
    firestore()
      .collection('Users')
      .add({
        name: inputDoc,
        contact: '',
        address: '',
      })
      .then(() => {
        setInputDoc('');
        alert('Added');
      })
      .catch((error) => {
        alert(`Exception: ${error}`);
      });
  };

  const onDocRemove = (oldDoc) => {
    firestore()
      .collection('Users')
      .doc(oldDoc)
      .delete()
      .catch((error) => {
        alert(`Exception: ${error}`);
      });
  };

  const renderDoc = (doc, index) => {
    return (
      <View style={styles.card} key={index}>
        <Text>Id: {doc.id}</Text>
        <Text>Name: {doc.name}</Text>
        <Text>Contact: {doc.contact}</Text>
        <Text>Address: {doc.address}</Text>
        <Mybutton
          title="Remove"
          customClick={() => onDocRemove(doc.id)}
        />
      </View>
    );
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.container}>
        <View style={styles.inputContainer}>
          <TextInput
            style={styles.inputStyle}
            placeholder="Enter Name"
            onChangeText={
              (inputDoc) => setInputDoc(inputDoc)
            }
            value={inputDoc}
          />
          <Mybutton
            title="Submit"
            customClick={onDocSubmit}
          />
        </View>
        <ScrollView>
          {listData.map((doc, index) => renderDoc(doc, index))}
        </ScrollView>
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 5,
  },
  inputContainer: {
    flexDirection: 'row',
  },
  inputStyle: {
    flex: 1,
    maxWidth: 350,
    borderColor: 'black',
    height: 40,
    borderWidth: 0.5,
    backgroundColor: 'white',
    padding: 10,
    marginVertical: 10,
  },
  card: {
    padding: 10,
    backgroundColor: 'white',
    borderColor: '#E8E8E8',
    borderWidth: 1,
    borderBottomColor: '#D4D4D4',
    borderBottomWidth: 1,
    borderRadius: 2,
  },
});

export default RealTimeAddUpdateUser;

页面/AddOrderSummary.js

在此屏幕中,您将看到用于搜索用户的输入,如果找到,您将看到添加记录选项,该选项将在用户文档中添加一些虚拟订单汇总集合。

// #2 Integration of Firebase Cloud Firestore Database
// https://aboutreact.com/react-native-firebase-cloud-firestore-db

import React, {useState} from 'react';
import {View} from 'react-native';
import Mytextinput from './components/Mytextinput';
import Mybutton from './components/Mybutton';
import firestore from '@react-native-firebase/firestore';

const AddOrderSummary = () => {
  // We will insert these Dummy Order in use collection
  const dummyOrder = (
    {
      itemId: 1,
      itemName: 'T-Shirt',
      itemQuantity: 5,
      amount: 5000,
    },
    {
      itemId: 2,
      itemName: 'Shoe',
      itemQuantity: 2,
      amount: 2000,
    },
  );

  let (userId, setUserId) = useState('');
  let (userData, setUserData) = useState({});

  const searchUser = () => {
    if (userId) {
      firestore()
        .collection('Users')
        .doc(userId)
        .get()
        .then((documentSnapshot) => {
          let userDetails = {};
          if (documentSnapshot.exists) {
            userDetails = documentSnapshot.data();
            userDetails('id') = documentSnapshot.id;
          }
          setUserData(userDetails);
        });
    }
  };

  const updateOrder = () => {
    if (userId) {
      let newOrderCollection = firestore()
        .collection('Users')
        .doc(userId)
        .collection('ordersummary');
      dummyOrder.forEach((item) => {
        newOrderCollection
          .add(item)
          .then(() => {
            alert('Added Successfully');
          })
          .catch((error) => {
            alert(`Exception: ${error}`);
          });
      });
    }
  };

  return (
    <View style={{paddingHorizontal: 35}}>
      <Mytextinput
        placeholder="Enter User Id"
        onChangeText={(userId) => setUserId(userId)}
        value={userId}
        style={{padding: 10}}
      />
      <Mybutton
        title="Search User"
        customClick={searchUser}
      />
      {Object.keys(userData).length ? (
        <Mybutton
          title="Add Order in User Document"
          customClick={updateOrder}
        />
      ) : null}
    </View>
  );
};

export default AddOrderSummary;

运行 React Native 应用程序

再次打开终端并使用跳转到您的项目。

cd ProjectName

1. 启动 Metro Bundler

首先,您需要启动 Metro,React Native 附带的 JavaScript 捆绑器。 要启动 Metro 捆绑程序,请运行以下命令

npx react-native start

一旦您启动 Metro Bundler,它将永远在您的终端上运行,直到您将其关闭。 让 Metro Bundler 在自己的终端中运行。 打开一个新终端并运行该应用程序。

2.启动React Native应用程序

在 Android 虚拟设备或真实调试设备上运行项目

npx react-native run-android

或在 iOS 模拟器上运行(仅限 macOS)

npx react-native run-ios

启用蜕皮

您将收到一个 app:mergeDexDebug 添加 Cloud Firestore 后出错,请阅读 启用多重分包 有关如何解决此错误的更多信息,请参阅文档。

输出截图

React_native_firebase_cloud_firestore_1
React_native_firebase_cloud_firestore_2_create_record.png
React_native_firebase_cloud_firestore_3_update_record.pngReact_native_firebase_cloud_firestore_4_remove_record.png
React_native_firebase_cloud_firestore_5_view_record.png
React_native_firebase_cloud_firestore_6_view_all_record.png
React_native_firebase_cloud_firestore_7_suscription.png
React_native_firebase_cloud_firestore_8_create_nested_record.png

离线支持

Firestore 为离线功能提供开箱即用的支持。 在读取和写入数据时,Firestore 使用本地数据库,该数据库会自动与服务器同步。 当用户处于离线状态时,Firestore 功能将继续运行,并在用户重新获得连接时自动将数据迁移到服务器。

默认情况下启用此功能,但如果您需要禁用它(例如在包含敏感信息的应用程序上),则可以禁用它。 必须在执行任何 Firestore 交互之前调用 settings() 方法,否则它只会在下一次应用程序启动时生效

import firestore from '@react-native-firebase/firestore';

async function bootstrap() {
  await firestore().settings({
    persistence: false, // disable offline persistence
  });
}

这就是如何将 Firebase Cloud Firestore 数据库与适用于 Android 和 iOS 的 React Native 应用程序集成。 如果您有任何疑问或想分享有关该主题的内容,您可以在下面发表评论或在此处联系我们

推荐:Elementor动画插件Lottier Lottie Animated Images for Elementor


发表评论