Can't add data to Firestore collection?

Viewed 674

I'm new to React Native/Expo. I'm trying to integrate Firebase Firestore with my app so I can persist some data.

I've created a file firebase.js in a folder called config:

import * as firebase from "firebase";
import "firebase/firestore";

const firebaseConfig = {
  // All the relevant firebase config data is here, removed for this post
};

// Initialize Firebase
if (!firebase.apps.length) {
  const app = firebase.initializeApp(firebaseConfig).firestore();
} else {
  const app = firebase.app().firestore();
}

In my App.js, I'm trying to save the latitude and longitude of the device to Firestore:

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

import firebase from "./config/firebase";

import * as Location from 'expo-location';

export default function App() {
  const [location, setLocation] = useState(null);
  const [errorMsg, setErrorMsg] = useState(null);

  const add = (x, y) => {
    if (x === null || x === "" || y === null || y === "") {
      return false;
    }

    firebase.collection("users")
      .doc(1)
      .set({
        x: x,
        y: y
      });
  };

  useEffect(() => {
    (async () => {
      let { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        setErrorMsg('Permission to access location was denied');
        return;
      }

      let location = await Location.getCurrentPositionAsync({});
      setLocation(location);
    })();
  }, []);

  let text = 'Waiting..';
  if (errorMsg) {
    text = errorMsg;
  } else if (location) {
    text = JSON.stringify(location);

    add(location.coords.latitude, location.coords.longitude);
  }

  return (
    <View style={styles.container}>
      <Text style={styles.paragraph}>{text}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Fairly straightforward stuff.

However, when I run this, I get an error:

Component Exception

_firebase.default.collection is not a function. (In '_firebase.default.collection("users")`, '_firebase.default.collection' is undefined)

What am I doing wrong?

Thanks

3 Answers

You aren't showing what you export as firestore from ./config/firebase, but it must be what you're expecting.

According to the Firebase Documentation, you want to be doing something along these lines:

var db = firebase.firestore()
db.collection("users").doc //etc

So, in this scenario, you'd want to export db as firestore in your config/firebase/

Note that this is for version 8 of the web API, which I'm assuming you're using based on your code checking firebase.apps.length. If you're using version 9, you'll need to update your code for the new API.

By the way, you’re importing libraries as the example in the documentation. Apparently, you’re using version 9 of the SDK (modular), therefore, the way of managing data is different. You can compare the differences here.

As in the documentation, version 8 was made as follows:

// Add a new document in collection "cities"
db.collection("cities").doc("LA").set({
    name: "Los Angeles",
    state: "CA",
    country: "USA"
})

In version 9, it should be done this way:

import { doc, setDoc } from "firebase/firestore"; 

// Add a new document in collection "cities"
await setDoc(doc(db, "cities", "LA"), {
  name: "Los Angeles",
  state: "CA",
  country: "USA"
});

You should also check the firestore version you are running and set up your environment accordingly.

import * as firebase from "firebase";
import "firebase/firestore";

const firebaseConfig = {
  // All the relevant firebase config data is here, removed for this post
};

// Initialize Firebase
if (!firebase.apps.length) {
  const app = firebase.initializeApp(firebaseConfig).firestore();
export default app;
} else {
  const app = firebase.app().firestore();
export default app;
}

Before you use import firebase from "./config/firebase"; you need to export Default; so that the imported variable "firebase" will be either "firebase.app().firestore();" or "firebase.initializeApp(firebaseConfig).firestore()"

you can then firebase.collection("users") .doc(1) .set({ x: x, y: y }); because the variable firebase is actually firestore

Related