admin管理员组

文章数量:1399982

I'm using firebase in my reactjs+typescript project. I want to write a document in firebase and I'm using setDoc to do this job.

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

setDoc(doc(database, `path`), objData)

When you check the function return it says Promise<...>. But, how am I supposed to use then() catch() promise handlers if I don't know what the promise returns when it fullfil/reject?

I'm using firebase in my reactjs+typescript project. I want to write a document in firebase and I'm using setDoc to do this job.

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

setDoc(doc(database, `path`), objData)

When you check the function return it says Promise<...>. But, how am I supposed to use then() catch() promise handlers if I don't know what the promise returns when it fullfil/reject?

Share Improve this question asked Dec 17, 2021 at 22:16 jgsnevesjgsneves 911 silver badge6 bronze badges 6
  • Often when it is a promise the .then() will have a result and then .catch() will have an error. So you would want to add a .then(result) and then do something with that, perhaps .then(result -> {...}) – ConnerWithAnE Commented Dec 17, 2021 at 22:20
  • I never used firestore, but isn't this the related documentation? It clearly says export declare function setDoc<T>(reference: DocumentReference<T>, data: WithFieldValue<T>): Promise<void>;, what is so difficult here? – ASDFGerte Commented Dec 17, 2021 at 22:28
  • 3 Firestore's setDoc returns a Promise<void>, so there's no result in the then(). The catch will get an error, as FivePaperFly says and the then gets no argument - it being called simply signals that the promise was successfully pleted. – Frank van Puffelen Commented Dec 17, 2021 at 22:29
  • yea I know that but when I try then(result => result) result has void typo!! hahahaha some Promises has the type of its return in generic, aka: Promise<onSucessType> – jgsneves Commented Dec 17, 2021 at 22:30
  • @FrankvanPuffelen In my opinion, it could return the document ref onSuccess.... no? hahaha – jgsneves Commented Dec 17, 2021 at 22:31
 |  Show 1 more ment

4 Answers 4

Reset to default 3

I'm not very familiar with Firebase but after looking around it seems the return is just going to be whether or not the setDoc() was successful. So the .then() would mean yes and the .catch() would mean no. So really all you would want is something like this

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

setDoc(doc(database, `path`), objData)
.then(() => {
console.log("Successful")})
.catch((error) => {
console.log(`Unsuccessful returned error ${error}`)});

Again I am not fully sure about the exact values returned as I could not find much but if there is a result value given you would place it in the .then((result) => {console.log(result)}).

The firebase documentation suggest using await, so here you have a plete example of error handling with await and cleanup with finally.

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


async function run() {
    try {
        await setDoc(doc(database, `path`), objData)
    } catch (e) {
        console.error(e); // handle your error here
    } finally {
        console.log('Cleanup here'); // cleanup, always executed
    }
}

run();

In Typescript, you don't need to specify the promise return type precisely. Here's an example of how to use promise handlers with setDoc:

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

setDoc(doc(database, `path`), objData)
  .then((data) => {console.log('data', data);})
  .catch((err) => {console.log('err', err);})

I found some odd behavior. I'm making a handler function in Angular that calls a Firebase Cloud Function that writes to Firestore. I'm using the emulator.

app.ponent.ts

  wordRequest(word: string, l2Language: L2Language, requestOrigin: string) {
    const buildWordObject = httpsCallableFromURL(this.functions, 'http://localhost:5001/my-app/us-central1/buildWordObject');
    buildWordObject({
      word: word,
      l2Language: l2Language,
      requestOrigin: requestOrigin
    })
      .then((result) => {
        console.log(result.data);
        if (result.data === null) {
          console.log("Success! Word object written to database.");
        }
      })
      .catch((error) => {
        console.error(error);
      });
  }

index.js

export const buildWordObject = functions.https.onCall((data, context) => {
    ...does various stuff here

    setDoc(doc(firestore, 'Dictionaries/' + longLanguage + '/Words', word), wordObject)
        .then(() => {
            console.log("Finished writing word object to Firestore database: " + word);
            return 37
        })
        .catch((error: any) => {
            console.error(error);
            return error
        });
    return 38
});

This logs Finished writing word object to Firestore database: luck in the emulator console and logs 38 in the Angular console.

If I ment out return 38 the emulator log is the same but in the Angular console I see:

Success! Word object written to database.

Either way the data is written to the Firestore emulator.

A successful database write returns null to the Angular handler function that called it. I don't see Success! for a few seconds so it's clearly doing something async.

If I ment out return 37 and return error then everything runs without errors. Usually when I write a Firebase Cloud Function without a return statement it throws an error in the log.

What I find odd is that the return to the Angular handler is always null, never 37. The console.log message writes to the emulator log but the return 37 statement never executes. You can't return anything but null back to the calling function.

I tried putting .finally(() => { return 37 }); at the end but I never got 37 back.

本文标签: javascriptWhat does setDoc function returnStack Overflow