0
0
React Nativemobile~20 mins

Why Firebase powers mobile backends in React Native - Build It to Prove It

Choose your learning style9 modes available
Build: Firebase Features Demo
This screen shows why Firebase is a great choice for mobile backends by demonstrating user authentication and real-time data updates.
Target UI
---------------------------------
| Firebase Features Demo         |
|-------------------------------|
| [Sign In Button]               |
|                               |
| Messages:                     |
| - Welcome to Firebase!         |
|                               |
| [Add Message Button]           |
---------------------------------
Add a Sign In button that simulates user login
Display a list of messages stored in Firebase Realtime Database
Add a button to add a new message to the database
Show real-time updates when messages change
Use Firebase Authentication and Realtime Database
Starter Code
React Native
import React, { useState, useEffect } from 'react';
import { View, Text, Button, FlatList, StyleSheet } from 'react-native';
import { initializeApp } from 'firebase/app';
import { getDatabase, ref, onValue, push } from 'firebase/database';
import { getAuth, signInAnonymously } from 'firebase/auth';

const firebaseConfig = {
  // TODO: Add your Firebase config here
};

const app = initializeApp(firebaseConfig);
const database = getDatabase(app);
const auth = getAuth(app);

export default function FirebaseFeaturesDemo() {
  const [user, setUser] = useState(null);
  const [messages, setMessages] = useState([]);

  // TODO: Add sign-in handler

  // TODO: Add real-time messages listener

  // TODO: Add function to add new message

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Firebase Features Demo</Text>
      <Button title="Sign In" onPress={() => { /* TODO */ }} />
      <Text style={styles.subtitle}>Messages:</Text>
      <FlatList
        data={messages}
        keyExtractor={item => item.id}
        renderItem={({ item }) => <Text style={styles.message}>- {item.text}</Text>}
      />
      <Button title="Add Message" onPress={() => { /* TODO */ }} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, marginTop: 40 },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 10 },
  subtitle: { fontSize: 18, marginTop: 20, marginBottom: 10 },
  message: { fontSize: 16, marginVertical: 2 }
});
Task 1
Task 2
Task 3
Solution
React Native
import React, { useState, useEffect } from 'react';
import { View, Text, Button, FlatList, StyleSheet } from 'react-native';
import { initializeApp } from 'firebase/app';
import { getDatabase, ref, onValue, push } from 'firebase/database';
import { getAuth, signInAnonymously, onAuthStateChanged } from 'firebase/auth';

const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  databaseURL: "YOUR_DATABASE_URL",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
};

const app = initializeApp(firebaseConfig);
const database = getDatabase(app);
const auth = getAuth(app);

export default function FirebaseFeaturesDemo() {
  const [user, setUser] = useState(null);
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
      setUser(currentUser);
    });
    return unsubscribe;
  }, []);

  const handleSignIn = () => {
    signInAnonymously(auth).catch(error => {
      console.error('Sign in error:', error);
    });
  };

  useEffect(() => {
    const messagesRef = ref(database, 'messages');
    const unsubscribe = onValue(messagesRef, (snapshot) => {
      const data = snapshot.val() || {};
      const parsedMessages = Object.entries(data).map(([id, value]) => ({ id, text: value.text }));
      setMessages(parsedMessages);
    });
    return () => unsubscribe();
  }, []);

  const addMessage = () => {
    const messagesRef = ref(database, 'messages');
    push(messagesRef, { text: 'Welcome to Firebase!' });
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Firebase Features Demo</Text>
      {!user ? (
        <Button title="Sign In" onPress={handleSignIn} />
      ) : (
        <Text>Signed in anonymously</Text>
      )}
      <Text style={styles.subtitle}>Messages:</Text>
      <FlatList
        data={messages}
        keyExtractor={item => item.id}
        renderItem={({ item }) => <Text style={styles.message}>- {item.text}</Text>}
      />
      <Button title="Add Message" onPress={addMessage} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, marginTop: 40 },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 10 },
  subtitle: { fontSize: 18, marginTop: 20, marginBottom: 10 },
  message: { fontSize: 16, marginVertical: 2 }
});

This app uses Firebase Authentication to sign in users anonymously, which is simple and requires no user input. It listens to the Firebase Realtime Database for messages under the 'messages' path and updates the UI in real-time whenever data changes. The Add Message button pushes a new message with the text 'Welcome to Firebase!' to the database. This demonstrates Firebase's power for mobile backends: easy authentication, real-time data syncing, and simple database writes, all with minimal code.

Final Result
Completed Screen
---------------------------------
| Firebase Features Demo         |
|-------------------------------|
| Signed in anonymously          |
|                               |
| Messages:                     |
| - Welcome to Firebase!         |
|                               |
| [Add Message Button]           |
---------------------------------
Tapping 'Sign In' signs in the user anonymously and changes the button to a signed-in message
Messages list updates live when new messages are added
Tapping 'Add Message' adds a new 'Welcome to Firebase!' message to the list
Stretch Goal
Add a loading spinner while signing in and disable buttons during loading
💡 Hint
Use a state variable to track loading and conditionally render ActivityIndicator and disable buttons