在前端调用时等待httpsCallable似乎不起作用



我使用的是云函数,我有httpsCallable,它向firestore数据库添加一条消息,该数据库在前端调用时正在等待。问题是,当我这样做时,结果会在调用定义它的函数之后得到解决。我不确定这是异步/等待问题还是云函数httpsCallable的问题。提前感谢

这是后端的代码:


// The Cloud Functions for Firebase SDK to create Cloud Functions
// and setup triggers.
const functions = require("firebase-functions");
// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
admin.initializeApp();

// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions
exports.helloWorld = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", {structuredData: true});
response.send("Hello from Firebase!");
});

// Take the text parameter passed to this HTTP endpoint and insert it into 
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
// Grab the text parameter.
const original = req.query.text;
// Push the new message into Firestore using the Firebase Admin SDK.
const writeResult = await admin.firestore().collection('messages').add({original: original});
// Send back a message that we've successfully written the message
res.json({result: `Message with ID: ${writeResult.id} added.`});
});
// a callable version of addMessage
exports.addMessageCallable = functions.https.onCall(async (data, context) => {
// ...
const original = data.text;
// Push the new message into Firestore using the Firebase Admin SDK.
const writeResult = await admin.firestore().collection('messages').add({original: original});
console.log("********** writeResult **********", writeResult.id)
// Send back a message that we've successfully written the message
return {
"success": true,
"message": data.text,
"documentId": writeResult.id
}
});

// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore.document('/messages/{documentId}')
.onCreate((snap, context) => {
// Grab the current value of what was written to Firestore.
const original = snap.data().original;
// Access the parameter `{documentId}` with `context.params`
functions.logger.log('Uppercasing', context.params.documentId, original);

const uppercase = original.toUpperCase();

// You must return a Promise when performing asynchronous tasks inside a Functions such as
// writing to Firestore.
// Setting an 'uppercase' field in Firestore document returns a Promise.
return snap.ref.set({uppercase}, {merge: true});
});

然后在前端:

import './App.css';
import firebase from "firebase";
import "firebase/functions";

// values being read from a .emv
const { REACT_APP_FB_API_KEY, REACT_APP_FB_AUTH_DOMAIN, REACT_APP_FB_PROJECTID, REACT_APP_FB_STORAGE_BUCKET,REACT_APP_FB_MSG_SENDER_ID, REACT_APP_FB_APP_ID, REACT_APP_FB_MEASUREMENT_ID } = process.env;
// initialize the SDK
const firebaseConfig = {
apiKey: REACT_APP_FB_API_KEY,
authDomain: REACT_APP_FB_AUTH_DOMAIN,
projectId: REACT_APP_FB_PROJECTID,
storageBucket: REACT_APP_FB_STORAGE_BUCKET,
messagingSenderId: REACT_APP_FB_MSG_SENDER_ID,
appId: REACT_APP_FB_APP_ID,
measurementId: REACT_APP_FB_MEASUREMENT_ID
};
firebase.initializeApp(firebaseConfig);
// Initialize Cloud Functions through Firebase
const functions = firebase.functions();
function App() {
const sampleFunc1 = () => {
console.log("**** 2 ******")
// calls sampleFunc1
sampleFunc2();
};
const sampleFunc2 = () => {
console.log("**** 3 ******")
// calls addMsgFunc
addMsgFunc();
};
const addMsgFunc = async () => {
console.log("**** 4 ******")
const addMessage = functions.httpsCallable('addMessageCallable');
try {
console.log("**** 5: before result ******")
const result = await addMessage({ text: "working!!" });
console.log("********* 6. result ******", result.data)
console.log("**** 7: after result ******")
} catch (error) {
console.error("**** err: *****", error)
}
};
const handleClick = () => {
console.log("**** 1 ******")
sampleFunc1()
console.log("**** 8. done ******")
}
return (
<div className="App">
<div>
<h3>hello world!</h3>
<button onClick={handleClick}>click me</button>
</div>
</div>
);
}
export default App;


// here's the result that I get
// **** 1 ******
// **** 2 ******
// **** 3 ******
// **** 4 ******
// **** 5: before result ******
// **** 8. done ******
// ********* 6. result ******
// **** 7: after result ******
// What I actually want
// **** 1 ******
// **** 2 ******
// **** 3 ******
// **** 4 ******
// **** 5: before result ******
// ********* 6. result ******
// **** 7: after result ******
// **** 8. done ******

你可以在这个github repo 中找到整个代码

您也应该await父函数,因为它们是async(或返回promise(,否则函数将继续处理第8部分而不等待第6,7部分。

function App() {
const sampleFunc1 = async () => {
console.log("**** 2 ******")
// calls sampleFunc1
await sampleFunc2();
};
const sampleFunc2 = async () => {
console.log("**** 3 ******")
// calls addMsgFunc
await addMsgFunc();
};
const addMsgFunc = async () => {
console.log("**** 4 ******")
const addMessage = functions.httpsCallable('addMessageCallable');
try {
console.log("**** 5: before result ******")
const result = await addMessage({ text: "working!!" });
console.log("********* 6. result ******", result.data)
console.log("**** 7: after result ******")
} catch (error) {
console.error("**** err: *****", error)
}
};
const handleClick = async () => {
console.log("**** 1 ******")
await sampleFunc1()
console.log("**** 8. done ******")
}
return (
<div className="App">
<div>
<h3>hello world!</h3>
<button onClick={handleClick}>click me</button>
</div>
</div>
);
}

addMsgFunc函数是异步的,但在sampleFunc2中调用它时没有使用wait。我还使示例函数异步。如果仍然不起作用,请告诉我。

最新更新