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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

560閲覧

next.js + firebase hosting + cloud function でPWAを実現したい

tky5622

総合スコア4

Firebase

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2018/07/25 10:05

編集2018/07/25 13:32

前提・実現したいこと

next.js + firebase hosting + cloud function でPWAを実現したい

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

こちらのnext.js+firebase hostingにservice-workerを追加してPWA化をしようとしています。しかし、hostingまでは動くのですが、service-worker.jsの実行が上手くいかず困っています。
https://github.com/zeit/next.js/tree/canary/examples/with-firebase-hosting

登録までの流れとしては
①nextのビルド時にworkboxを使ってservice-worker.jsファイルを作成して、
firebase hosting へデプロイを行うfunctionsフォルダ配下へnextフォルダごとコピー
②デプロイ後、_document.js内で、
navigator.serviceWorker.register('/service-worker')
を実行して/service-workerへfetch
③ /service-workerへのfetchをcloud functionで検知して、
service-worker.jsを実行

以上の流れになっています。

しかし、404エラーで登録に失敗しています。
おそらく、service-worker.jsのパスが上手く指定できていないことが原因だと思われますが、どのようにしたら登録が可能になるかお聞きしたいです。

エラーメッセージ Service worker registration failed, error1: TypeError: Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script.

該当のソースコード

ソースコード (functions/index.js) const functions = require('firebase-functions'); const next = require('next'); import * as admin from 'firebase-admin'; const { join } = require('path'); const { parse } = require('url'); const express = require('express'); const routes = require('./routes'); // Region hosting next.js to cloud function const dev = process.env.NODE_ENV !== 'production'; const app = next({ dev, conf: { distDir: 'next' } }); const handle = routes.getRequestHandler(app); const server = express(); server.get('*', (req, res) => handle(req, res)); server.get('/service-worker', (req, res) => { // いくつかパスを書き換えて試してみましたが、いづれもうまく動きませんでした。 // app.serveStatic(req, res, '_next/service-worker.js'), // app.serveStatic(req, res, 'next/service-worker.js'); // app.serveStatic(req, res, '/service-worker.js'); // app.serveStatic(req, res, '/next/service-worker.js'); const filePath = join(__dirname , 'service-worker.js') app.serveStatic(req, res, filePath); }); exports.next = functions.https.onRequest((req, res) => { console.log('File: ' + req.originalUrl); // log the page.js file that is being requested return app.prepare().then(() => { server(req, res); }); });

試したこと

プロジェクトの構成(firebase hosting へデプロイされるdistフォルダと、build前のフォルダ構成)
イメージ説明
イメージ説明

json

1firebase.jsonの設定 2{ 3 "hosting": { 4 "public": "dist/public", 5 "ignore": [ 6 "firebase.json", 7 "**/.*", 8 "**/node_modules/**" 9 ], 10 "rewrites": [ 11 { 12 "function": "next", 13 "source": "**/**" 14 } 15 ], 16 "predeploy": "npm run build-public" 17 }, 18 "functions": { 19 "source": "dist/functions", 20 "predeploy": 21 "npm run build-funcs && npm run build-app && npm run copy-deps && npm run install-deps" 22 } 23} 24

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

"next": "^6.1.1", "next-offline": "^2.8.0", "node": ">=8.1.4", "npm": ">=5.4.2" "next-routes": "^1.4.2",

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

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

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

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

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

guest

回答2

0

functions/ ├ index.js └ next/ └ service-worker.js

のようなディレクトリ構造になっているなら

javascript

1const filePath = join(__dirname , 'next/service-worker.js'); 2app.serveStatic(req, res, filePath);

__dirname で functions ディレクトリの絶対パスが取れてるはずなのでこれでいけると思います。

投稿2018/07/25 12:51

yhg

総合スコア2161

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

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

tky5622

2018/07/25 13:18

ご回答ありがとうございます。 build後の構造はそのようになっているのですが、上記の修正では動作しませんでした。 ディレクトリ構造についての細くは画像で追加させていただきました。
guest

0

自己解決

自己解決しました。
server.get * を削除したところ、適切にファイルを認識することができました。

投稿2018/07/25 20:01

tky5622

総合スコア4

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

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

tky5622

2018/07/25 23:03

今回の場合は、server.getの順番でワイルドカードが順番的に上に配置されていたことが原因のようでした。 また、その他のmanifest.jsonなどの静的ファイルは基本的に、こちらのcloud function内でパスを通すことで参照できることもわかりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問