1
1

More than 3 years have passed since last update.

[メモ]Cloud Functions + Node.jsでさくっとAPI開発

Posted at

たまにはfirebaseでAPIを作りたくなったので、作ってみました。
次気が向いたとき、さくっと作れるように。

firebase --version 
9.1.0

プロジェクトを作成する

まずGUIでプロジェクトを作成し、課金モードにしておくのが楽。

https://console.firebase.google.com/u/0/
cd desktop
mkdir api
cd api

連携/初期化

必要に応じて、有効化する。ひとまずFunctionsだけ有効化してみる。

$ mkdir api 
$ cd api
$ firebase init

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

You're about to initialize a Firebase project in this directory:

  /Users/user/Desktop/api

? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. 
 ◯ Database: Configure Firebase Realtime Database and deploy rules
 ◯ Firestore: Deploy rules and create indexes for Firestore
❯◉ Functions: Configure and deploy Cloud Functions
 ◯ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules
 ◯ Emulators: Set up local emulators for Firebase features
 ◯ Remote Config: Get, deploy, and rollback configurations for Remote Config
=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add, 
but for now we'll just set up a default project.

? Please select an option: (Use arrow keys)
❯ Use an existing project 
  Create a new project 
  Add Firebase to an existing Google Cloud Platform project 
  Don't set up a default project 

? Please select an option: Use an existing project
? Select a default Firebase project for this directory: 
  xxxxxxxx (yyyy) 
❯ api-189bf (api) 
  xxxxxxxx (yyyyy) 
  xxxxxxxx (yyyyy) 
=== Functions Setup

A functions directory will be created in your project with a Node.js
package pre-configured. Functions can be deployed with firebase deploy.

? What language would you like to use to write Cloud Functions? (Use arrow keys)
❯ JavaScript 
  TypeScript 
? What language would you like to use to write Cloud Functions? JavaScript
? Do you want to use ESLint to catch probable bugs and enforce style? Yes
✔  Wrote functions/package.json
✔  Wrote functions/.eslintrc.json
✔  Wrote functions/index.js
✔  Wrote functions/.gitignore
? Do you want to install dependencies with npm now? Yes

> protobufjs@6.10.2 postinstall /Users/inoueyousuke/Desktop/api/functions/node_modules/protobufjs
> node scripts/postinstall

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...
i  Writing gitignore file to .gitignore...

✔  Firebase initialization complete!

helloWorldをデプロイ

/functions/index.js

const functions = require('firebase-functions');

// // 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!");
// });

コメントアウトを削除する

/functions/index.js

const functions = require('firebase-functions');

// // 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!");
 });

デプロイ!!

firebase deploy

=== Deploying to 'api-189bf'...

i  deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run lint

> functions@ lint /Users/user/Desktop/api/functions
> eslint .

✔  functions: Finished running predeploy script.
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i  functions: ensuring required API cloudbuild.googleapis.com is enabled...
⚠  functions: missing required API cloudbuild.googleapis.com. Enabling now...
✔  functions: required API cloudfunctions.googleapis.com is enabled
✔  functions: required API cloudbuild.googleapis.com is enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (33.28 KB) for uploading
✔  functions: functions folder uploaded successfully
i  functions: creating Node.js 12 function helloWorld(us-central1)...
✔  functions[helloWorld(us-central1)]: Successful create operation. 
Function URL (helloWorld): https://us-central1-api-189bf.cloudfunctions.net/helloWorld

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/api-189bf/overview

生成されたエンドポイントにアクセスする

スクリーンショット 2021-03-26 3.15.50.png

完成

フロントから叩けるPOSTAPIを作る

CORSが面倒なので、以下参照で回避

functions/index.js
const functions = require("firebase-functions");

exports.post = functions.https.onRequest(async (request, response) => {

  //CORS用にAccess-Control-Allow系ヘッダを追加
  response.set("Access-Control-Allow-Origin", "https://xxxxxx.com");
  //DELETEだけは拒否
  response.set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS, POST");
  //Content-Typeのみを許可
  response.set("Access-Control-Allow-Headers", "Content-Type");
  // dataフィールドに渡したい値は入れる
  response.json({ data: "hello!!" });
});

Cloud Funtionsでnpmモジュールを使う

./functions

npm install xxx

あとは普通にindex.jsを書くだけ。

Fire Storeとか使いたい

上の章を参考に導入。
こちらの記事参照

npm i firebase-admin --save
/functions/index.js
const functions = require('firebase-functions')
// cloud functionでfirestoreを使うのに必要な設定は以下の2行
const admin = require('firebase-admin')
admin.initializeApp(functions.config().firebase)

// データベースの参照を作成
var fireStore = admin.firestore()

exports.helloWorld = functions.https.onRequest((request, response) => {
  // 動作確認のため適当なデータをデータベースに保存
  var citiesRef = fireStore.collection('cities');
  citiesRef.doc('SF').set({
    name: 'San Francisco', state: 'CA', country: 'USA',
    capital: false, population: 860000 })

  var cityRef = fireStore.collection('cities').doc('SF')
  cityRef.get()
  .then(doc => {
    if (!doc.exists) {
      response.send('No such document!')
    } else {
      response.send(doc.data())
      }
    })
    .catch(err => {
      response.send('not found')
    })
})

ひとまずこんな感じで幸せになれます!
エミュレータとかも書きたかったけど、また気が向いたときにやってみよう。

バイバイ!

参照

cloud functionsでfirestoreを使う
Markdown の画像に枠線をつける
FirebaseのCloud FunctionsでCORSが~とかAccess-Control-Allow-Originが~と言われたらこれ

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1