Ravi Mishra
Ravi Mishra

Reputation: 11

Unable to Upload Image to Firebase in React Native, TypeError: Cannot read property 'showImagePicker' of undefined, js engine: hermes

I'm working on a React Native project where I need to upload an image to Firebase. I'm using react-native-image-picker for image selection and @react-native-firebase/firestore for interacting with Firestore. The form works well, and the text fields store data in Firebase correctly, but the image field in Firebase shows null.

I am receiving an error when I try to upload the image after clicking the "Select Image" button. The image URI is not stored in Firestore, and instead, it shows null. Please see the provided screenshots!

Steps to reproduce:

  1. Click on the "Select Image" button.

  2. Pick an image from the device.

  3. Click on the "Submit" button.

Expected behavior: The image URI should be saved in Firestore along with the other ticket data.

Actual behavior: An error occurs when I click the select button, and the image URI is not uploaded to Firestore; it shows null instead.

Environment:

  1. React Native version: 0.74.1

  2. react-native-image-picker version: 7.1.2

  3. @react-native-firebase/firestore version: 20.1.0

Code is below -

// Importing necessary libraries
import React, { useEffect, useState } from "react";
import { View, Text, StyleSheet, TouchableOpacity, Image, Alert, TextInput } from "react-native";
import ImagePicker from "react-native-image-picker";
import { firebase } from "@react-native-firebase/firestore";

// Importing firebaseConfig for Firestore
import { firestore } from "../firebaseConfig";

// Defining NewTicket component
export default function NewTicket({ route, navigation }) {
  // Destructuring parameters from route
  const { uid, phoneNumber } = route.params;
  // State variables
  const [ticketData, setTicketData] = useState("");
  const [image, setImage] = useState(null);
  const [users, setUsers] = useState([]);
  // Firestore reference
  const todoRef = firebase.firestore().collection("users");

  // Fetching data useEffect hook
  useEffect(() => {
    const fetchData = async () => {
      const querySnapshot = await todoRef.where("phoneNumber", "==", phoneNumber).get();
      const fetchedUsers = [];
      querySnapshot.forEach((doc) => {
        const { name, phoneNumber, designation, usertype } = doc.data();
        fetchedUsers.push({
          id: doc.id,
          name: name || "",
          phoneNumber: phoneNumber || "",
          designation: designation || "",
          usertype: usertype || "",
        });
      });
      setUsers(fetchedUsers.length > 0 ? fetchedUsers : [{ id: "0", name: "", phoneNumber: "", designation: "", usertype: "" }]);
    };

    fetchData();
  }, [phoneNumber]);

  // Input handler function
  const handleInput = (text) => {
    setTicketData(text);
  };

  // Image selection function
  const selectImage = () => {
    console.log("select image");
    const options = {
      title: "Select Image",
      storageOptions: {
        skipBackup: true,
        path: "images",
      },
    };

    ImagePicker.showImagePicker(options, (response) => {
      if (response.didCancel) {
        console.log("User cancelled image picker");
      } else if (response.error) {
        console.log("ImagePicker Error: ", response.error);
      } else {
        const source = { uri: response.uri };
        setImage(source);
      }
    });
  };

  // Submit function
  const submit = async () => {
    try {
      const user = users[0];
      await firestore()
        .collection("ticketData")
        .doc()
        .set({
          ticketData,
          name: user.name,
          imageUri: image ? image.uri : null,
        });
      console.log("submitted");
      Alert.alert(
        "Submitted",
        "Your ticket has been submitted successfully!",
        [
          {
            text: "OK",
            onPress: () => navigation.goBack(),
          },
        ],
        { cancelable: false }
      );
    } catch (error) {
      console.error("Error saving details: ", error);
    }
  };

  // Return JSX
  return (
    <View style={styles.main}>
      <Image source={require("../assets/assetsApp/impressions_logo.webp")} style={styles.image} />
      <Text style={styles.formHeadingText}>New Ticket Page</Text>
      <Text style={styles.belowHeading}>Fill your basic details to complete your ticket</Text>
      <View>
        <TextInput style={styles.formInput} placeholder="Enter ticket name" value={ticketData} onChangeText={handleInput} />
        <TouchableOpacity onPress={selectImage} style={styles.selectButton}>
          <Text style={styles.textSelectButton}>Select Image</Text>
        </TouchableOpacity>
        {image && <Image source={image} style={{ width: 200, height: 200, marginTop: 10 }} />}
        <TouchableOpacity onPress={submit} style={styles.submitButton}>
          <Text style={styles.textSubmitButton}>Submit</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}

Any help would be appreciated. Thanks!

PACKAGE.JSON FILE CODE --

{
  "name": "my-app",
  "version": "1.0.0",
  "main": "expo/AppEntry.js",
  "scripts": {
    "start": "expo start --dev-client",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@expo/metro-runtime": "~3.2.1",
    "@expo/vector-icons": "^14.0.0",
    "@react-native-firebase/app": "^20.1.0",
    "@react-native-firebase/auth": "^20.1.0",
    "@react-native-firebase/firestore": "^20.1.0",
    "@react-native-firebase/storage": "^20.1.0",
    "@react-native-masked-view/masked-view": "0.3.1",
    "@react-navigation/native": "^6.1.17",
    "@react-navigation/native-stack": "^6.9.26",
    "@react-navigation/stack": "^6.3.29",
    "expo": "^51.0.14",
    "expo-dev-client": "~4.0.15",
    "expo-image-picker": "~15.0.5",
    "expo-permissions": "^14.4.0",
    "expo-status-bar": "~1.12.1",
    "firebase": "^10.12.2",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-native": "0.74.1",
    "react-native-gesture-handler": "~2.16.1",
    "react-native-image-picker": "^7.1.2",
    "react-native-paper": "^5.12.3",
    "react-native-safe-area-context": "^4.10.1",
    "react-native-screens": "^3.31.1",
    "react-native-web": "~0.19.10",
    "typescript": "~5.3.3"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@types/react-native": "^0.73.0"
  },
  "private": true
}

Upvotes: 0

Views: 34

Answers (0)

Related Questions