- 둘다 배포하면 https url이 할당된다.
onCall은 Firebase와 통합된 앱 내에서 사용하기 위한 것임. 본질적으로 onCall은 firebase에게 http 요청을 관리하도록 지시하는 것.
onRequest는 엔드포인트를 설정하는데 사용함. 즉, firebase의 통합 앱이 아닌 기능을 사용할 때에는 onRequeset를 사용하고, firebase 통합 앱의 기능을 사용할 경우에는 onCall을 사용하면 훨씬 간단하게 할 수 있다.
cloud functions의 용도 중 하나는 http API임. 근데 onCall은 RESTful 패턴을 따를 수 없다(오직 POST만 가능). 그래서 RESTful 이런 식으로 Cloud functions를 사용하는 경우에는 onRequest를 사용하고, Express로 API를 작성하고 React에서 API를 fetch와 같은 Web API로 호출하는 것이 좋다.
onCall는 데이터를 전달하여 원하는 리소스를 전달하는 대신에, RESTful을 따르고 URL에 리소스 경로를 넣는 것이 더 관용적이어야 한다. 하지만 이 과정은 자체 인증을 해야하므로(onCall이 인증 및 권한 부여를 대신 처리함) 토큰을 찾아 API에 전달하고 함수에서 토큰을 직접 확인해야 한다.
onCall
https://firebase.google.com/docs/functions/callable-reference
https://firebase.google.com/docs/functions/callable
- POST
- 매개변수 2개: data, context(선택사항)
- 사용자가 제공한 데이터(data)와 자동 컨텍스트(context)로 이뤄진다.
export const getUser = functions.https.onCall((data, context) => {
if (!context.auth) return {status: 'error', code: 401, message: 'Not signed in'}
return new Promise((resolve, reject) => {
// find a user by data.uid and return the result
resolve(user)
})
})
- 컨텍스트에는 uid, 토큰과 같은 요청에 대한 메타데이터가 자동으로 포함됨
- Firebase 인증 토큰, FCM 토큰, 앱 체크 토큰이 있는 경우에 자동으로 요청(context)에 포함된다.
- 헤더에 반드시 이게 포함되어야 함 Content-Type: application/json
-클라이언트 앱에서 직접 호출할 수 있다.
functions.httpsCallable('getUser')({uid})
.then(r => console.log(r.data.email))
- 결과 반환: 데이터를 클라이언트에 다시 전송(request)하려면 JSON 형식의 데이터를 반환해야 함. 아래는 예제.
- 데이터(data)와 응답(response)는 자동으로 (역)직렬화됨
onRequest
https://firebase.google.com/docs/functions/http-events
- GET, POST, PUT, DELETE, OPTIONS, ... 등 지원되는 HTTP 메서드 모두 가능
- API 엔드포인트 역할을 함
- request, response로 이뤄짐
export const getUser = functions.https.onRequest((req, res) => {
// verify user from req.headers.authorization etc.
res.status(401).send('Authentication required.')
// if authorized
res.setHeader('Content-Type', 'application/json')
res.send(JSON.stringify(user))
})
- 사용자가 입력한 인증 헤더에 따라 다름
- request, response 데이터는 만든이에 따라 달라짐
- 결과 반환: res.status(200).send(데이터)
onRequest로 elasticsearch하기
코드
exports.onSearchCompany = functions.https.onRequest(async (req, res) => {
try {
const { companyName } = req.query;
const searchRes = await client.search({
index: "company",
body: {
query: {
match: {
companyName: companyName,
},
},
},
});
const hits = searchRes.body.hits.hits;
console.log(hits);
const companyList = hits.map((h) => h["_source"]);
res.status(200).send(companyList);
} catch (err) {
console.error(err);
}
});
결과
참고 자료
https://www.py4u.net/discuss/282341