質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

メール

メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

Q&A

解決済

1回答

1873閲覧

Firebase Cloud Functionsからメールが送信できない

DeepSea

総合スコア4

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

メール

メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

0グッド

0クリップ

投稿2021/05/30 23:53

前提・実現したいこと

Firebase Storageにアップロードがあったタイミングで、該当するファイルを添付したメールを送信する仕組みを作ろうとしています。
メールの送信部分をFireabse Cloud Functionsから行おうとしているのですが、上手く動いていません。
原因と解決方法をご教示いただけますと幸いです。

発生している問題・エラーメッセージ

Fireabse Cloud Functionsにデプロイした関数は実行されている様です。
実行時に次のログが出力されています。

ダウンロード完了:xxx メール送信準備開始 Function終了

メール送信処理周りの次のログは出力されませんでした。

メール送信準備完了。メール送信開始 エラーあるいは「メール送信完了」

該当のソースコード

TypeScript

1import * as functions from "firebase-functions"; 2import * as admin from "firebase-admin"; 3import * as path from "path"; 4import * as os from "os"; 5import * as fs from "fs"; 6 7const nodemailer = require("nodemailer"); 8const app = admin.initializeApp(); 9 10export const test = functions.storage.object().onFinalize(async (object) => { 11 const fileBucket = object.bucket!; 12 const filePath = object.name!; 13 const fileName = path.basename(filePath); 14 const bucket = app.storage().bucket(fileBucket); 15 const tempFilePath = path.join(os.tmpdir(), fileName); 16 17 await bucket.file(filePath).download({destination: tempFilePath}); 18 functions.logger.log("ダウンロード完了: ", tempFilePath); 19 20 const transport = nodemailer.createTransport({ 21 service: "gmail", 22 auth: { 23 user: "xxx@gmail.com", 24 pass: "xxxxxxxx", 25 } 26 }); 27 28 functions.logger.log("メール送信準備開始"); 29 exports.sendMail = functions.https.onCall((data, context) => { 30 const mail = { 31 from: "xxx@gmail.com", 32 to: "yyy@gmail.com", 33 subject: "Firebase Cloud Functionsからテスト送信", 34 text: "テスト本文", 35 }; 36 37 functions.logger.log("メール送信準備完了。メール送信開始"); 38 transport.sendMail(mail, (error: any, info: any) => { 39 fs.unlinkSync(tempFilePath); 40 if (error) { 41 functions.logger.log(error); 42 } else { 43 functions.logger.log("メール送信完了"); 44 } 45 }); 46 }); 47 48 return functions.logger.log("Function終了"); 49});

試したこと

ネットで情報を探しながらプログラムを組んでみたのですが、知識不足から原因が特定できていません。
exports.sendMailに代入している処理全般が動いていない様なので、exports.sendMailを実行する方法が分かれば解決する様な気がしています。

補足情報(FW/ツールのバージョンなど)

package.jsonの内容は次の通りです。

{ "name": "functions", "scripts": { "build": "tsc", "serve": "npm run build && firebase emulators:start --only functions", "shell": "npm run build && firebase functions:shell", "start": "npm run shell", "deploy": "firebase deploy --only functions", "logs": "firebase functions:log" }, "engines": { "node": "14" }, "main": "lib/index.js", "dependencies": { "firebase-admin": "^9.8.0", "firebase-functions": "^3.14.1", "nodemailer": "^6.6.1" }, "devDependencies": { "firebase-functions-test": "^0.2.0", "typescript": "^3.8.0" }, "private": true }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

exports.sendMailに処理を代入するだけでは動きません。
中で定義している処理を実際に呼び出す必要があります。

...が、このコードの範囲内においてはわざわざ代入する必要はありません。
datacontextも必要とせず、これより前に必要な変数を準備しているので、
そのデータを粛々と処理するだけで十分だと思います。

Diff

1 functions.logger.log("メール送信準備開始"); 2- exports.sendMail = functions.https.onCall((data, context) => { 3 const mail = { 4 from: "xxx@gmail.com", 5 to: "yyy@gmail.com", 6 subject: "Firebase Cloud Functionsからテスト送信", 7 text: "テスト本文", 8 }; 9 10 functions.logger.log("メール送信準備完了。メール送信開始"); 11 transport.sendMail(mail, (error: any, info: any) => { 12 fs.unlinkSync(tempFilePath); 13 if (error) { 14 functions.logger.log(error); 15 } else { 16 functions.logger.log("メール送信完了"); 17 } 18 }); 19- });

exports.sendMail = でやっている事自体は、export constとほぼ同じでCloud Functions for Firebaseでは、「Functionsの呼び出し口を宣言する」ことになります。
が、firebase deployなどの際にはexports.sendMailは存在しないため、無意味な処理になってしまっています。
(もちろん、バケットへのアップロード時にて呼び出しFunction内で定義されるかもしれませんが、そのタイミングだけのものです)

投稿2021/05/31 00:50

編集2021/05/31 03:45
attakei

総合スコア2740

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DeepSea

2021/05/31 03:01

詳細なご回答、ありがとうございます! お陰様でメールの送信に成功できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問