Home > Software engineering >  Firebase realtime database get function returns undefined (newer firebase version, 2021) - using Rea
Firebase realtime database get function returns undefined (newer firebase version, 2021) - using Rea

Time:12-10

I'm using realtime database from Firebase. I've already set everything up to be able to access the information, when I log inside the function it returns the value alright.

I've tried this:

export default function BookCard(){
  const [bookListData, setBookListData] = useState([]);
  const [isLoading, setLoading] = useState(true);

  useEffect(() => {
    loadBooks();
  });

  function loadBooks() {
    try {
      const bookArray = getBookList();
      console.log(`Where: BookCard.jsx loadBooks(). Expects: Object with book info. Got: ${bookArray}`);
      setBookListData(bookArray);
    } catch (e) {
      setBookListData(null);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div>
      {console.log(`Where: BookCard.jsx return(). Expects: Object with book info. Got: ${bookListData}`)}
      <p>Hello world</p>
      <div>
        {isLoading
          ? 'Loading...'
          : bookListData}
      </div>
    </div>
  );
}

And, in another file:

const app = initializeApp(firebaseConfig);

const base_url = (hid link here);

const database = getDatabase(app, base_url);

export function getBookList() {
  const reference = ref(database);
  get(child(reference, '/books')).then((snapshot) => {
    if (snapshot.exists()) {
      const result = snapshot.val().results;
      console.log(`Where: api.js getBookList(). Expects: Object with book info. Got:`);
      console.log(result);
      return("result");
    } else {
      return 'No data available';
    }
  }).catch(() => {
    return 'Error fetching, try again';
  });
}

As you can see, I've placed a few logs all around, to try and see where the error is happening. The import is alright, as getBookList() is actually being called. This is what I get in the console:

Where: BookCard.jsx loadBooks(). Expects: Object with book info. Got: undefined
Where: BookCard.jsx return(). Expects: Object with book info. Got: undefined
Where: api.js getBookList(). Expects: Object with book info. Got:
(51) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

So it works inside the function, but the "return" still gives me undefined. I've tried a few work arounds that I've seen, like this:

export function getBookList() {
  const reference = ref(database);
  let desiredData = null;
  fetchData();
  console.log(`Where: api.js getBookList(). Expects: Object with book info. Got:`);
  console.log(desiredData);
  return (desiredData);

  function fetchData(){
    get(child(reference, '/books')).then((snapshot) => {
      if (snapshot.exists()) {
        const result = snapshot.val().results;
        console.log(`Where: api.js fetchData(). Expects: Object with book info. Got:`);
        console.log(result);
        desiredData = result;
      } else {
        desiredData = 'No data available';
      }
    }).catch(() => {
      desiredData = 'Error fetching, try again';
    });
  }
}

And the console returns

Where: api.js getBookList(). Expects: Object with book info. Got:
null
Where: BookCard.jsx loadBooks(). Expects: Object with book info. Got: null
Where: BookCard.jsx return(). Expects: Object with book info. Got: null
Where: api.js fetchData(). Expects: Object with book info. Got:
(51) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

I have no idea what to do. Every atempt to solve this problem I've seen uses outdated FireBase functions and such.

CodePudding user response:

The main issue I see here is that the getBookList is not returning anything (you are not returning the get request). So a good start would be to replace get(child(reference, '/books')).then((snapshot) => .. with return get(child(reference, '/books')).then((snapshot) => ...

Second issue seems to be that you inside getBookList function you are returning the string "result" (instead of the const containing the results). So you should also replace return("result"); with return result;

So for start you should have something like:

export function getBookList() {
  const reference = ref(database);
  return get(child(reference, '/books')).then((snapshot) => {
    if (snapshot.exists()) {
      const result = snapshot.val().results;
      console.log(`Where: api.js getBookList(). Expects: Object with book info. Got:`);
      console.log(result);
      return result;
    } else {
      return 'No data available';
    }
  }).catch(() => {
    return 'Error fetching, try again';
  });
}

But I am also wondering why are you using snapshot.val().results? If the data you want is under /books/results you should request it like so(return get(child(reference, '/books/results')).then((snapshot)). Or you need to check if the books collections exists in the first place? Than you could use

if (snapshot.exists()) { 
    const result = snapshot.child("results").val(); 
    ...

You can read more about child method (of a DataSnapshot)

Anyway is really hard to tell if this are all the issues (without a working example) but I hope this should at the very least give you a direction.

  • Related