teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

4

説明の修正

2020/12/12 03:47

投稿

Linkey
Linkey

スコア77

title CHANGED
File without changes
body CHANGED
@@ -28,7 +28,7 @@
28
28
  export default admin
29
29
  ```
30
30
 
31
- index.vueでユーザー一覧取得処理を呼び出す。
31
+ index.vueでユーザー一覧取得処理を呼び出す。
32
32
  index.vue
33
33
  ```vue
34
34
  <template>
@@ -135,7 +135,13 @@
135
135
  </style>
136
136
 
137
137
  ```
138
+ ⑤サーバー起動
139
+ yarn run dev
140
+
141
+ ⑥アプリケーションにアクセスする
142
+ http://localhost:3000/
143
+
138
- この実装で動作確認を行うと「Cannot read property 'auth' of undefined」と表示されてしまいます。
144
+ アプリケーションにアクセスすると「Cannot read property 'auth' of undefined」と表示されてしまいます。
139
145
  解決方法について探していますが、なかなか解決できません。
140
146
  Firebase Admin SDKの初期化手順が間違っているのでしょうか?
141
147
  そもそもnuxtアプリケーションにFirebase Admin SDKを導入することはできないのでしょうか?

3

タイトルと説明を修正。

2020/12/12 03:46

投稿

Linkey
Linkey

スコア77

title CHANGED
@@ -1,1 +1,1 @@
1
- Nuxt.jsでFirebaseの認証ユーザー一覧を取得した
1
+ Nuxt.jsでFirebase Admin SDK初期化がうまくかない
body CHANGED
@@ -1,280 +1,143 @@
1
1
  Nuxt.jsを勉強しているものです。
2
- Nuxt.jsのWebアプリケーションでFirebaseの認証ユーザーの一覧を取得してテーブル形式で表示させようとしています。
2
+ Nuxt.jsのWebアプリケーションでFirebaseの認証ユーザーの一覧を取得する処理を実装しようとしています。
3
- 実装は以下のようにしました。
4
3
 
4
+ 作業手順
5
+ ①プロジェクト作成
5
- pages/index.vue
6
+ yarn create nuxt-app sample
6
- ```Vue
7
- <template>
8
- <div>
9
- <Users />
10
- </div>
11
- </template>
12
7
 
13
- <script>
14
- import { Users } from "~/components/Users";
15
- export default {
16
- components: {
17
- Users
18
- },
19
- }
20
- </script>
8
+ ②firebase-adminをインストール
9
+ npm install firebase-admin --save
21
10
 
22
- <style>
23
-
24
- </style>
11
+ ③plugins配下にfirebaseAdmin.jsを作成
25
12
 
13
+ plugins/firebaseAdmin.js
14
+ ```js
15
+ const admin = (function () {
16
+ if (process.server) {
17
+ const a = require('firebase-admin');
18
+ if (!a.apps.length) {
19
+ const serviceAccount = require('../key.json');
20
+ a.initializeApp({
21
+ credential: a.credential.cert(serviceAccount),
22
+ databaseURL: 'XXXXXXXXXX'
23
+ });
24
+ }
25
+ return a;
26
+ }
27
+ })();
28
+ export default admin
26
29
  ```
27
30
 
28
- /components/Users.vue
31
+ ③index.vueでユーザー一覧取得処理を呼び出す。
32
+ index.vue
29
- ```Vue
33
+ ```vue
30
34
  <template>
31
35
  <div class="container">
36
+ <div>
37
+ <Logo />
38
+ <h1 class="title">
32
- ユーザ一覧
39
+ sample
40
+ </h1>
33
- <!-- TODO ここにテーブル形式でユーザー一覧を表示させる -->
41
+ <div class="links">
42
+ <a
43
+ href="https://nuxtjs.org/"
44
+ target="_blank"
45
+ rel="noopener noreferrer"
46
+ class="button--green"
47
+ >
48
+ Documentation
49
+ </a>
50
+ <a
51
+ href="https://github.com/nuxt/nuxt.js"
52
+ target="_blank"
53
+ rel="noopener noreferrer"
54
+ class="button--grey"
55
+ >
56
+ GitHub
57
+ </a>
58
+ </div>
59
+ </div>
34
60
  </div>
35
61
  </template>
36
62
 
37
63
  <script>
38
- import firebase from '~/plugins/firebase'
64
+ import admin from '~/plugins/firebaseAdmin'
39
-
40
65
  export default {
41
66
  data() {
42
- return {};
67
+ return {
68
+ }
43
69
  },
44
70
  mounted() {
71
+ const listAllUsers = (nextPageToken) => {
45
- // ユーザー一覧を取得する。
72
+ // List batch of users, 1000 at a time.
73
+ admin
74
+ .auth()
75
+ .listUsers(1000, nextPageToken)
76
+ .then((listUsersResult) => {
46
- let users = firebase.auth().listUsers(1000).then((listUsersResult) => {
77
+ listUsersResult.users.forEach((userRecord) => {
47
- console.log('user:', JSON.stringify(listUsersResult));
78
+ console.log('user', userRecord.toJSON());
48
- });
79
+ });
80
+ if (listUsersResult.pageToken) {
81
+ // List next batch of users.
82
+ listAllUsers(listUsersResult.pageToken);
83
+ }
84
+ })
85
+ .catch((error) => {
86
+ console.log('Error listing users:', error);
87
+ });
88
+ };
89
+ // Start listing users from the beginning, 1000 at a time.
90
+ listAllUsers();
91
+
49
92
  },
50
- methods: {
51
- }
52
93
  }
53
94
  </script>
54
- ```
55
95
 
96
+ <style>
97
+ .container {
98
+ margin: 0 auto;
99
+ min-height: 100vh;
100
+ display: flex;
101
+ justify-content: center;
102
+ align-items: center;
56
- /plugins/firebase.js
103
+ text-align: center;
57
- ```Vue
104
+ }
58
- import firebase from 'firebase'
59
105
 
106
+ .title {
107
+ font-family:
108
+ 'Quicksand',
60
- if (!firebase.apps.length) {
109
+ 'Source Sans Pro',
110
+ -apple-system,
61
- firebase.initializeApp(
111
+ BlinkMacSystemFont,
112
+ 'Segoe UI',
62
- {
113
+ Roboto,
63
- apiKey: "XXXXXXX",
114
+ 'Helvetica Neue',
115
+ Arial,
116
+ sans-serif;
117
+ display: block;
64
- authDomain: "XXXXXX",
118
+ font-weight: 300;
65
- databaseURL: "XXXXXXX",
119
+ font-size: 100px;
120
+ color: #35495e;
66
- projectId: "XXXXXXXXX",
121
+ letter-spacing: 1px;
67
- storageBucket: "XXXXX",
68
- messagingSenderId: "XXXXXX",
69
- appId: "XXXXXXXXXXXX",
70
- measurementId: "XXXXXXXXX"
71
- }
72
- )
73
122
  }
74
- export default firebase
75
- ```
76
123
 
77
- この状態で実行すると
124
+ .subtitle {
78
- listUsers関数が見つかりませんというエラーが発生します。
79
- javascriptではFirebaseの認証ユーザー一覧を取得することはできないのでしょうか?
80
- Firebase APIに詳しい方がいましたらご回答いただけないでしょうか?
81
- よろしくお願いいたします。
125
+ font-weight: 300;
82
-
83
- -- 追記 --
84
- https://gurutaka-log.com/nuxt-firebase-auth-serviceworker#STEP4firebase-admin
85
- https://gurutaka-log.com/nuxtserverinit-firestore
86
- 上記サイトを参考に以下のように実装してみました。
87
-
88
- nuxt.config.json
126
+ font-size: 42px;
89
- ```json
90
- export default {
127
+ color: #526488;
91
- (中略)
92
- workbox: {
128
+ word-spacing: 5px;
93
- importScripts: [
129
+ padding-bottom: 15px;
94
- "https://www.gstatic.com/firebasejs/7.6.1/firebase-app.js",
95
- "https://www.gstatic.com/firebasejs/7.6.1/firebase-auth.js",
96
- "https://www.gstatic.com/firebasejs/6.2.4/firebase-database.js",
97
- "sw-firebase-auth.js"
98
- ],
99
- dev: process.env.MODE != "production",
100
- },
101
- (省略)
102
130
  }
103
- ```
104
131
 
105
- static/sw-firebase-auth.js
106
- ```json
107
- // firebaseを初期化
108
- firebase.initializeApp({
109
- apiKey: XXXXXXX,
110
- authDomain: XXXXXXXXX,
111
- databaseURL: XXXXXXXXXX,
112
- projectId: XXXXXXXXXXX,
113
- storageBucket: XXXXXXXXXXX,
114
- messagingSenderId: XXXXXXXXXXXXX,
115
- appId: XXXXXXXXXXXXX,
116
- measurementId: XXXXXXXXXXXXX
117
- });
118
-
119
- // onAuthStateChanged()で現在のuserからidTokenを取得
120
- const getIdToken = () => {
121
- return new Promise((resolve, reject) => {
122
- const unsubscribe = firebase.auth().onAuthStateChanged(user => {
123
- unsubscribe();
124
- if (user) {
125
- user.getIdToken().then(
126
- idToken => resolve(idToken),
127
- error => resolve(null)
128
- );
129
- } else {
132
+ .links {
130
- resolve(null);
131
- }
132
- });
133
- });
134
- };
135
-
136
- // URLからルートのURLを取得する処理
137
- const getOriginFromUrl = url => {
138
- // https://stackoverflow.com/questions/1420881/how-to-extract-base-url-from-a-string-in-javascript
139
- const pathArray = url.split("/");
140
- const protocol = pathArray[0];
141
- const host = pathArray[2];
142
- return protocol + "//" + host;
143
- };
144
-
145
- /**
146
- * Service Workderのライフサイクルでfetchしたときの処理
147
- */
148
- self.addEventListener("fetch", event => {
149
-
150
- // リクエストをラップして、ヘッダにFirebase AuthのIdTokenを追加する処理
151
- const requestProcessor = idToken => {
152
- let req = event.request;
153
- // URLを取得して、httpsもしくはlocalhostかなどをチェック
154
- if (self.location.origin == getOriginFromUrl(event.request.url) &&
155
- (self.location.protocol == "https:" || self.location.hostname == "localhost") &&
156
- idToken
157
- ) {
158
- // ヘッダ情報をクローンする
159
- const headers = new Headers();
160
- for (let entry of req.headers.entries()) {
161
- headers.append(entry[0], entry[1]);
162
- }
163
- // クローンしたヘッダにFirebase AuthのIdTokenを追加
164
- headers.append("Authorization", "Bearer " + idToken);
165
- try {
166
- req = new Request(req.url, {
167
- method: req.method,
168
- headers: headers,
169
- mode: "same-origin",
170
- credentials: req.credentials,
171
- cache: req.cache,
172
- redirect: req.redirect,
173
- referrer: req.referrer,
174
- body: req.body,
175
- bodyUsed: req.bodyUsed,
176
- context: req.context
177
- });
178
- } catch (e) {
179
- console.error(e);
180
- }
181
- }
182
- return fetch(req);
183
- };
184
-
185
- // 上の関数を使って、全リクエストでIdTokenの取得し、Firebase AuthのIdTokenを追加ようにする
186
- event.respondWith(getIdToken().then(requestProcessor, requestProcessor));
187
- });
188
-
189
- /**
190
- * Service Workderのライフサイクルでactivateしたときの処理
191
- */
192
- self.addEventListener("activate", event => {
193
- event.waitUntil(clients.claim());
194
- });
195
- ```
196
-
197
- plugins/firebaseAdmin.js
198
- ```javascript
199
- let admin
200
-
201
- if (process.server) {
202
- admin = require('firebase-admin')
203
- if (!admin.apps.length) {
204
- const serviceAccount = require('key.json')
205
- admin.initializeApp({
133
+ padding-top: 15px;
206
- credential: admin.credential.cert(serviceAccount),
207
- databaseURL: "XXXXXXXXXXXXXXX"
208
- })
209
- }
210
134
  }
211
- export default admin
135
+ </style>
212
- ```
213
136
 
214
- /components/Users.vue
215
- ```Vue
216
- <template>
217
- <div class="container">
218
- ユーザ一覧
219
- </div>
220
- </template>
221
-
222
- <script>
223
- export default {
224
- data() {
225
- return {};
226
- },
227
-
228
- created() {},
229
-
230
- // 計算等
231
- computed: {},
232
-
233
- // 監視
234
- watch: {
235
-
236
- },
237
- filters: {
238
- },
239
- mounted() {
240
- this.nuxtServerInit();
241
- },
242
-
243
- methods: {
244
- async nuxtServerInit() {
245
- // firebase-adminの初期化
246
- const admin = require('~/plugins/firebaseAdmin').default;
247
-   let users = admin.auth().listUsers(1000).then((listUsersResult) => {
248
-  console.log('user:', JSON.stringify(listUsersResult));
249
-   });
250
- }
251
- }
252
- }
253
- </script>
254
137
  ```
255
-
256
- この状態で動作確認すると以下のエラーが発生します。
257
- Uncaught (in promise) TypeError: Cannot read property 'auth' of undefined
138
+ この実装で動作確認を行うと「Cannot read property 'auth' of undefined」と表示されてしまいます。
258
- admin.firestore().collectionの部分でエラーとなってしまいfirebaseの初期化がうまくいきません。
259
- また、workboxを使ってfirebaseのライブラリを読み込んでいるはずが以下の警告が出てしまいます。
260
-
261
- It looks like you're using the development build of the Firebase JS SDK.
262
- When deploying Firebase apps to production, it is advisable to only import
263
- the individual SDK components you intend to use.
264
-
265
- For the module builds, these are available in the following manner
266
- (replace <PACKAGE> with the name of a component - i.e. auth, database, etc):
267
-
268
- CommonJS Modules:
269
- const firebase = require('firebase/app');
270
- require('firebase/<PACKAGE>');
271
-
272
- ES Modules:
273
- import firebase from 'firebase/app';
274
- import 'firebase/<PACKAGE>';
275
-
276
- Typescript:
277
- import firebase from 'firebase/app';
278
- import 'firebase/<PACKAGE>';
279
-
280
- なかなか問題が解決できないですが、解決方法を確認しています。
139
+ 解決方法について探していますが、なかなか解決できません
140
+ Firebase Admin SDKの初期化手順が間違っているのでしょうか?
141
+ そもそもnuxtアプリケーションにFirebase Admin SDKを導入することはできないのでしょうか?
142
+ Firebaseに詳しい方がいましたら、ご回答いただけないでしょうか
143
+ よろしくお願いいたします。

2

拡張子を記載

2020/12/12 03:45

投稿

Linkey
Linkey

スコア77

title CHANGED
File without changes
body CHANGED
@@ -25,7 +25,7 @@
25
25
 
26
26
  ```
27
27
 
28
- /components/Users
28
+ /components/Users.vue
29
29
  ```Vue
30
30
  <template>
31
31
  <div class="container">
@@ -211,7 +211,7 @@
211
211
  export default admin
212
212
  ```
213
213
 
214
- /components/Users
214
+ /components/Users.vue
215
215
  ```Vue
216
216
  <template>
217
217
  <div class="container">

1

追記を追加

2020/12/11 00:44

投稿

Linkey
Linkey

スコア77

title CHANGED
File without changes
body CHANGED
@@ -78,4 +78,203 @@
78
78
  listUsers関数が見つかりませんというエラーが発生します。
79
79
  javascriptではFirebaseの認証ユーザー一覧を取得することはできないのでしょうか?
80
80
  Firebase APIに詳しい方がいましたらご回答いただけないでしょうか?
81
- よろしくお願いいたします。
81
+ よろしくお願いいたします。
82
+
83
+ -- 追記 --
84
+ https://gurutaka-log.com/nuxt-firebase-auth-serviceworker#STEP4firebase-admin
85
+ https://gurutaka-log.com/nuxtserverinit-firestore
86
+ 上記サイトを参考に以下のように実装してみました。
87
+
88
+ nuxt.config.json
89
+ ```json
90
+ export default {
91
+ (中略)
92
+ workbox: {
93
+ importScripts: [
94
+ "https://www.gstatic.com/firebasejs/7.6.1/firebase-app.js",
95
+ "https://www.gstatic.com/firebasejs/7.6.1/firebase-auth.js",
96
+ "https://www.gstatic.com/firebasejs/6.2.4/firebase-database.js",
97
+ "sw-firebase-auth.js"
98
+ ],
99
+ dev: process.env.MODE != "production",
100
+ },
101
+ (省略)
102
+ }
103
+ ```
104
+
105
+ static/sw-firebase-auth.js
106
+ ```json
107
+ // firebaseを初期化
108
+ firebase.initializeApp({
109
+ apiKey: XXXXXXX,
110
+ authDomain: XXXXXXXXX,
111
+ databaseURL: XXXXXXXXXX,
112
+ projectId: XXXXXXXXXXX,
113
+ storageBucket: XXXXXXXXXXX,
114
+ messagingSenderId: XXXXXXXXXXXXX,
115
+ appId: XXXXXXXXXXXXX,
116
+ measurementId: XXXXXXXXXXXXX
117
+ });
118
+
119
+ // onAuthStateChanged()で現在のuserからidTokenを取得
120
+ const getIdToken = () => {
121
+ return new Promise((resolve, reject) => {
122
+ const unsubscribe = firebase.auth().onAuthStateChanged(user => {
123
+ unsubscribe();
124
+ if (user) {
125
+ user.getIdToken().then(
126
+ idToken => resolve(idToken),
127
+ error => resolve(null)
128
+ );
129
+ } else {
130
+ resolve(null);
131
+ }
132
+ });
133
+ });
134
+ };
135
+
136
+ // URLからルートのURLを取得する処理
137
+ const getOriginFromUrl = url => {
138
+ // https://stackoverflow.com/questions/1420881/how-to-extract-base-url-from-a-string-in-javascript
139
+ const pathArray = url.split("/");
140
+ const protocol = pathArray[0];
141
+ const host = pathArray[2];
142
+ return protocol + "//" + host;
143
+ };
144
+
145
+ /**
146
+ * Service Workderのライフサイクルでfetchしたときの処理
147
+ */
148
+ self.addEventListener("fetch", event => {
149
+
150
+ // リクエストをラップして、ヘッダにFirebase AuthのIdTokenを追加する処理
151
+ const requestProcessor = idToken => {
152
+ let req = event.request;
153
+ // URLを取得して、httpsもしくはlocalhostかなどをチェック
154
+ if (self.location.origin == getOriginFromUrl(event.request.url) &&
155
+ (self.location.protocol == "https:" || self.location.hostname == "localhost") &&
156
+ idToken
157
+ ) {
158
+ // ヘッダ情報をクローンする
159
+ const headers = new Headers();
160
+ for (let entry of req.headers.entries()) {
161
+ headers.append(entry[0], entry[1]);
162
+ }
163
+ // クローンしたヘッダにFirebase AuthのIdTokenを追加
164
+ headers.append("Authorization", "Bearer " + idToken);
165
+ try {
166
+ req = new Request(req.url, {
167
+ method: req.method,
168
+ headers: headers,
169
+ mode: "same-origin",
170
+ credentials: req.credentials,
171
+ cache: req.cache,
172
+ redirect: req.redirect,
173
+ referrer: req.referrer,
174
+ body: req.body,
175
+ bodyUsed: req.bodyUsed,
176
+ context: req.context
177
+ });
178
+ } catch (e) {
179
+ console.error(e);
180
+ }
181
+ }
182
+ return fetch(req);
183
+ };
184
+
185
+ // 上の関数を使って、全リクエストでIdTokenの取得し、Firebase AuthのIdTokenを追加ようにする
186
+ event.respondWith(getIdToken().then(requestProcessor, requestProcessor));
187
+ });
188
+
189
+ /**
190
+ * Service Workderのライフサイクルでactivateしたときの処理
191
+ */
192
+ self.addEventListener("activate", event => {
193
+ event.waitUntil(clients.claim());
194
+ });
195
+ ```
196
+
197
+ plugins/firebaseAdmin.js
198
+ ```javascript
199
+ let admin
200
+
201
+ if (process.server) {
202
+ admin = require('firebase-admin')
203
+ if (!admin.apps.length) {
204
+ const serviceAccount = require('key.json')
205
+ admin.initializeApp({
206
+ credential: admin.credential.cert(serviceAccount),
207
+ databaseURL: "XXXXXXXXXXXXXXX"
208
+ })
209
+ }
210
+ }
211
+ export default admin
212
+ ```
213
+
214
+ /components/Users
215
+ ```Vue
216
+ <template>
217
+ <div class="container">
218
+ ユーザ一覧
219
+ </div>
220
+ </template>
221
+
222
+ <script>
223
+ export default {
224
+ data() {
225
+ return {};
226
+ },
227
+
228
+ created() {},
229
+
230
+ // 計算等
231
+ computed: {},
232
+
233
+ // 監視
234
+ watch: {
235
+
236
+ },
237
+ filters: {
238
+ },
239
+ mounted() {
240
+ this.nuxtServerInit();
241
+ },
242
+
243
+ methods: {
244
+ async nuxtServerInit() {
245
+ // firebase-adminの初期化
246
+ const admin = require('~/plugins/firebaseAdmin').default;
247
+   let users = admin.auth().listUsers(1000).then((listUsersResult) => {
248
+  console.log('user:', JSON.stringify(listUsersResult));
249
+   });
250
+ }
251
+ }
252
+ }
253
+ </script>
254
+ ```
255
+
256
+ この状態で動作確認すると以下のエラーが発生します。
257
+ Uncaught (in promise) TypeError: Cannot read property 'auth' of undefined
258
+ admin.firestore().collectionの部分でエラーとなってしまいfirebaseの初期化がうまくいきません。
259
+ また、workboxを使ってfirebaseのライブラリを読み込んでいるはずが以下の警告が出てしまいます。
260
+
261
+ It looks like you're using the development build of the Firebase JS SDK.
262
+ When deploying Firebase apps to production, it is advisable to only import
263
+ the individual SDK components you intend to use.
264
+
265
+ For the module builds, these are available in the following manner
266
+ (replace <PACKAGE> with the name of a component - i.e. auth, database, etc):
267
+
268
+ CommonJS Modules:
269
+ const firebase = require('firebase/app');
270
+ require('firebase/<PACKAGE>');
271
+
272
+ ES Modules:
273
+ import firebase from 'firebase/app';
274
+ import 'firebase/<PACKAGE>';
275
+
276
+ Typescript:
277
+ import firebase from 'firebase/app';
278
+ import 'firebase/<PACKAGE>';
279
+
280
+ なかなか問題が解決できないですが、解決方法を確認しています。