Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Nuxt.jsとFirebaseで爆速でPWA対応Webアプリを開発した話
Search
TakeshiNishi
December 08, 2018
Programming
4
1.3k
Nuxt.jsとFirebaseで爆速でPWA対応Webアプリを開発した話
フロントエンドカンファレンス福岡の発表スライドです。
NuxtとFirebaseを使って、PWA対応のリアルタイムWebチャットアプリケーションを開発した話をします。
TakeshiNishi
December 08, 2018
Tweet
Share
More Decks by TakeshiNishi
See All by TakeshiNishi
LT駆動開発 - 話題のChatGPTで何か作る
takec24
0
170
成長ステージ別のスタートアップ集結!「事業の魅力とチームの本音」
takec24
0
130
Developing FLAPTALK by Firebase
takec24
1
410
NuxtCompositionAPIとFirebaseの話
takec24
1
510
コロナ禍でもリモート案件を途切れさせない! 案件の獲得方法とリモート案件の進め方。
takec24
0
380
フロントエンドエンジニアのためのFirebaseサーバーレス開発徹底解説
takec24
0
1.2k
スタートアップで働くというエンジニアキャリア
takec24
1
1.2k
人生を変えた炎上ブロジェクト
takec24
0
1.5k
好きなことを選び続けたら代表取締役CTOになりました。
takec24
2
1.3k
Other Decks in Programming
See All in Programming
Pythonスレッドとは結局何なのか? CPython実装から見るNoGIL時代の変化
curekoshimizu
4
1.2k
ててべんす独演会〜Flowの全てを語ります〜
tbsten
1
220
麻雀点数計算問題生成タスクから学ぶ Single Agentの限界と Agentic Workflowの底力
po3rin
5
2.1k
CSC305 Lecture 02
javiergs
PRO
1
260
Learn CPU architecture with Assembly
akkeylab
1
1.3k
議事録の要点整理を自動化! サーバレス Bot 構築術
penpeen
3
1.6k
CI_CD「健康診断」のススメ。現場でのボトルネック特定から、健康診断を通じた組織的な改善手法
teamlab
PRO
0
160
パフォーマンスチューニングで Web 技術を深掘り直す
progfay
18
4.8k
複雑化したリポジトリをなんとかした話 pipenvからuvによるモノレポ構成への移行
satoshi256kbyte
1
720
AIエージェント時代における TypeScriptスキーマ駆動開発の新たな役割
bicstone
4
1.4k
階層構造を表現するデータ構造とリファクタリング 〜1年で10倍成長したプロダクトの変化と課題〜
yuhisatoxxx
3
870
非同期jobをtransaction内で 呼ぶなよ!絶対に呼ぶなよ!
alstrocrack
0
430
Featured
See All Featured
Statistics for Hackers
jakevdp
799
220k
Music & Morning Musume
bryan
46
6.8k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
45
2.5k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
358
30k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.9k
GitHub's CSS Performance
jonrohan
1032
460k
Building Adaptive Systems
keathley
43
2.8k
Why Our Code Smells
bkeepers
PRO
339
57k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
It's Worth the Effort
3n
187
28k
Transcript
/VYUKTͱ'JSFCBTFͰരͰ 18"ରԠ8FCΞϓϦΛ։ൃͨ͠ גࣜձࣾEJ⒎FBTZ औక$50 ࢙ GFD@GVLVPLB GFD@GVLVPLB@TBMMZ
None
࢙ גࣜձࣾEJ⒎FBTZ औక$50 !@UBLFTIJ@ 'JSFCBTF 7VF (PMBOH 3VCZ ($1 ϒϩοΫνΣʔϯ
EPDLFS /VYU &MJYJS Թઘ ϥϯχϯά ಡॻ
NBLFEJ⒏DVMUUIJOHTFBTZ ੈքதͷzΉ͔͍ͣ͠zΛ؆୯ʹ
EJ⒎FBTZͷ ϑϩϯτΤϯυ࢙ EJ⒎FBTZۀΤϯδχΞ δϣΠϯ 8FCΤϯδχΞਓ ϑϩϯτΤϯυK2VFSZ 7VFKT࠾༻ "OHVMBS3FBDUͰΉɾɾ
ࣗࣾαʔϏεʹ/VYUKT࠾༻
18"ରԠ8FCΞϓϦ
wϦΞϧλΠϜνϟοτΞϓϦ w͍ͨ͠ΩʔϫʔυͰܨ͕Δ wϝʔϧύεϫʔυೝূ wϓϩϑΟʔϧը૾Ξοϓϩʔυ w։ൃਓఔ ˞/VYUKTɺ'JSFCBTFֶशࡁΈ ˞Ћ൛ͳͷͰࡉ͔͍ڍಈະରԠ ։ൃͨ͠18"ରԠ8FCΞϓϦ
18"ͱԿ͔ʁ 1SPHSFTTJWF 8FC "QQT ωΠςΟϒΞϓϦͷΑ͏ʹಈ࡞͢Δ 8FCΞϓϦ
18"ͰԿ͕Ͱ͖Δʁ ᶃΠϯετʔϧʢϗʔϜը໘ʹΞΠίϯઃஔʣՄೳ
18"ͰԿ͕Ͱ͖Δʁ 1$൛$ISPNFͰ࣮ݧత֦ுػೳΛ༗ޮʹ͢Δͱ 18"ΛΠϯετʔϧͰ͖Δɻ
18"ͰԿ͕Ͱ͖Δʁ ΞυϨεόʔͳͲඇදࣔ
18"ͰԿ͕Ͱ͖Δʁ ᶄΦϑϥΠϯͰಈ࡞Մೳ wΦϑϥΠϯͰΞϓϦಈ࡞ wαʔόʔͱͷ௨৴ෆՄ w௨৴࠶։࣌ʹαʔόʔૹ৴ड৴
18"ͰԿ͕Ͱ͖Δʁ ᶅϓογϡ௨Մೳ wϓογϡ௨Մೳ wϢʔβʔ͝ͱʹݸผͷ௨Մೳ w௨͕දࣔ͞ΕΔ w௨ΛΫϦοΫͯ͠ΞϓϦىಈ ˞J04൛4BGBSJඇରԠ ࣌ ˞ϓογϡ௨0OF4JHOBMΛར༻
18"ͰԿ͕Ͱ͖Δʁ ᶆϖʔδͷදࣔվળ4FSWJDF8PSLFS w4FSWJDF8PSLFS͕ϓϩΩγͷׂ w$BDIF͔Βߴʹදࣔ wόοΫάϥϯυͰ࠷৽ͷίϯςϯ πΛऔಘ͠Ωϟογϡ wΦϑϥΠϯͰಈ͘ͷಉ͡Έ wϓογϡ௨Λड͚औΔ 4FSWJDF 8PSLFS
18" $BDIF 8FC
18"ͷࣄྫ 5XJUUFS-JUF wϒϥβ͔ΒϗʔϜը໘ʹΠϯετʔ ϧՄೳ wωΠςΟϒΞϓϦΑΓܰྔɻىಈ ͕͍ɻ wػೳҰ෦੍ݶ https://mobile.twitter.com
18"ͷࣄྫ ܦిࢠ൛ w͝Ζ͔Β͍ͪૣ͘18"։ൃ ΛਐΊΔ wఔͷվળ https://r.nikkei.com/
'JSFCBTFόοΫΤϯυ
'JSFCBTFͱԿ͔ʁ Google͕ఏڙ͢ΔBaaS(Backend as a Service)
'JSFCBTFͱԿ͔ʁ όοΫΤϯυ ϑϩϯτΤϯυ
/VYUKTϑϩϯτΤϯυ
/VYUKTͱԿ͔ʁ Vue.jsΞϓϦέʔγϣϯ։ൃ ͷͨΊͷϑϨʔϜϫʔΫɻ wϧʔςΟϯά7VF3PVUFS wঢ়ଶཧ7VFY 7VF൛'MVY w443 ʜͳͲ
/VYUKTº'JSFCBTFͷ։ൃ
'JSFCBTFͷ༻ҙ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶃϢʔβʔೝূ"VUIFOUJDBUJPO Firebase Authentication ʹϢʔβʔೝূͷΈ͕ఏڙ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶃϢʔβʔೝূ"VUIFOUJDBUJPO firebase .auth() .createUserWithEmailAndPassword(email, password) firebase .auth() .signInWithEmailAndPassword(email, password)
ΞΧϯτొ ϩάΠϯ firebase.auth().currentUser ϩάΠϯதΞΧϯτऔಘ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶄϦΞϧλΠϜσʔλϕʔε$MPVE'JSFTUPSF Vuex VuexFire Firestore
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶄϦΞϧλΠϜσʔλϕʔε ͭͷσʔλϕʔε͕ఏڙ͞Ε͍ͯΔ 3FBMUJNF%BUBCBTF $MPVE'JSFTUPSF Ќ ʻ ΫΤϦͷॊೈੑ ιʔτͷॊೈੑ কདྷੑ
બ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶄϦΞϧλΠϜσʔλϕʔε$MPVE'JSFTUPSF const messagesRef = db.collection(‘messages’) await messagesRef.add({ pairUid: data.pairUid,
uid: data.uid, text: data.text, time: Date.now() }) σʔλొ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶄϦΞϧλΠϜσʔλϕʔε$MPVE'JSFTUPSF σʔλొొ͞ΕͨσʔλΛ֬ೝ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶄϦΞϧλΠϜσʔλϕʔε$MPVE'JSFTUPSF const messagesRef = db.collection(‘messages’) export const state =
() => ({ messages: [], }) await bindFirebaseRef( 'messages', messagesRef .where('pairUid', '==', pairUid) .orderBy('time', 'desc') ) σʔλݕࡧ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶄϦΞϧλΠϜσʔλϕʔε$MPVE'JSFTUPSF const messagesRef = db.collection(‘messages’) await messagesRef .doc(id) .update({
text: data.text }) σʔλߋ৽
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶅετϨʔδ$MPVE4UPSBHF const storage = firebase.storage() const storageRef = storage.ref()
const avatarRef = storageRef .child('avatar/' + data.name) await avatarRef.put(data.file) ετϨʔδʹϑΝΠϧΛอଘ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶅετϨʔδ$MPVE4UPSBHF ετϨʔδʹϑΝΠϧΛอଘϑΝΠϧΛ֬ೝ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶅετϨʔδ$MPVE4UPSBHF const storage = firebase.storage() const storageRef = storage.ref()
const avatarUrl = await storageRef .child('avatar/' + user.avatar) .getDownloadURL() ετϨʔδͷϑΝΠϧΛμϯϩʔυ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶆϗεςΟϯά)PTUJOH pSFCBTFUPPMTΛΠϯετʔϧ $ yarn global add firebase-tools $
firebase init pSFCBTFϓϩδΣΫτͷॳظԽ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶆϗεςΟϯά)PTUJOH )PTUJOHΛબ
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶆϗεςΟϯά)PTUJOH ࡞ͨ͠ϓϩδΣΫτΛબ YYYYYYY YYYYYYY YYYYYYYYYYYYYYY YYYYYYY YYYYYYYYYYYYYYY YYYYYYY
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶆϗεςΟϯά)PTUJOH σϓϩΠ $ firebase deploy
/VYUKTͱ'JSFCBTFͷ࿈ܞ ᶆϗεςΟϯά)PTUJOH 'JSFCBTFͷϗεςΟϯάʹ ɹσϓϩΠ͞ΕΔ
18"ରԠ
/VYUKTͰ18"ରԠ !OVYUKTQXBΛར༻͢Ε ؆୯ʹ 18"ରԠʂ
/VYUKTͰ18"ରԠ $ yarn add @nuxtjs/pwa --save !OVYUKTQXBΛΠϯετʔϧ modules: [
'@nuxtjs/dotenv', '@nuxtjs/pwa' ], manifest: { name: 'wacha', short_name: 'wacha', title: 'wacha', lang: 'ja', gcm_sender_id: '103953800507' //ݻఆ }, OVYUDPOpHKTʹΞϓϦͷใΛՃ
/VYUKTͰ18"ରԠ TUBUJDJDPOQOHʹΞΠίϯը૾Λ༻ҙ Ҏ্ʂʂ
0OF4JHOBMͰϓογϡ௨
0OF4JHOBMͱʁ wແྉͷϓογϡ௨αʔϏε w"1*ΛݺͿ͜ͱͰϓογϡ௨Մೳ wಛఆͷλʔήοτ͚ͩʹ௨Մೳ w/VYUKTͷ18"Ϟδϡʔϧʹ 0OF4JHOBMରԠͷϞδϡʔϧ ༻ҙ͞Ε͍ͯΔ
0OF4JHOBMͷઃఆ
0OF4JHOBMͰϓογϡ௨ !OVYUKTPOFTJHOBMΛΠϯετʔϧ $ yarn add @nuxtjs/onesignal --save
0OF4JHOBMͰϓογϡ௨ modules: [ '@nuxtjs/dotenv', '@nuxtjs/onesignal', '@nuxtjs/pwa' ], oneSignal: { init:
{ appId: 'xxx-xxx-xxx-xxx-xxx', allowLocalhostAsSecureOrigin: true, welcomeNotification: { disable: true } } }, OVYUDPOpHKTʹ0OF4JHOBMͷใΛՃ
0OF4JHOBMͰϓογϡ௨ await this.$OneSignal.push([ 'sendTag', 'id', this.currentUser.uid, function(tagsSent) {} ])
UBHΛઃఆʢಛఆͷϢʔβʔͷΈʹ௨͢ΔͨΊʣ bJE`ͱ͍͏໊લͷλάͰɺ ϩάΠϯதͷϢʔβʔͷVJEͷΛઃఆ
0OF4JHOBMͰϓογϡ௨ const params = { method: 'post', url: 'https://onesignal.com/api/v1/notifications', headers:
{ 'Content-Type': 'application/json', Authorization: 'Basic zzzzzzzzzzzzzzzzzzzzzzzzz’ }, data: { app_id: 'xxx-xxx-xxx-xxx-xxx', headings: { ja: requestData.title }, contents: { ja: requestData.body }, tags: [{ key: 'id', relation: '=', value: requestData.uid }] } } axios(params) UBHΛࢦఆͯ͠ಛఆͷϢʔβʔͷΈʹ௨ ˞ݕূ༻ΞϓϦͷͨΊɺΫϥΠΞϯτͰ"1*ݺग़࣮͠
ৼΓฦΓ
'JSFCBTF࣮ࡍͲ͏ͳͷʁ wϑϩϯτΤϯυͷ։ൃͷΈͰɺϢʔβʔೝূɺϦΞϧ λΠϜσʔλϕʔεɺετϨʔδͷϑΝΠϧอଘͳ ͲΞϓϦʹඞཁͳػೳʂ w؆୯ͳνϟοτΞϓϦ50%0ΞϓϦϨϕϧͰ͋Ε ेͳػೳɻ
'JSFCBTF࣮ࡍͲ͏ͳͷʁ wΫΤϦ͕ශऑ ✴03ݕࡧෆՄɻΞϓϦͰΫΤϦ݁ՌΛ݁߹ɻ ✴લํҰகݕࡧՄೳɻ෦ҰகɺޙํҰகෆՄɻ ✴ൣғൺֱϑΟϧλ ͕͋Δ߹ɺ࠷ॳͷฒ ସ͑ಉ͡ϑΟʔϧυͰߦ͏ɻ citiesRef
.where("population", ">", 100000) .orderBy(“population")
'JSFCBTF࣮ࡍͲ͏ͳͷʁ wσʔλͷઃܭ͕େࣄ ϚΠάϨʔγϣϯେม ઌ΄ͲͷΞϓϦͷྫ "͞Μͱ#͞ΜͷϖΞͷτʔΫΛ Ұཡදࣔ͢ΔͨΊɺ ɾ"͞ΜͷҰཡදࣔ༻σʔλ ɾ#͞ΜͷҰཡදࣔ༻σʔλ Λ༻ҙɻ JOEFYFE1BJS\
\VJE" UBSHFU# QBJS*E^ \VJE# UBSHFU" QBJS*E^ \VJE" UBSHFU$ QBJS*E^ \VJE$ UBSHFU" QBJS*E^ \VJE# UBSHFU$ QBJS*E^ ɾɾɾ
'JSFCBTF࣮ࡍͲ͏ͳͷʁ w'JSFCBTFͷઃఆΛؒҧ͑ͯ࣌ؒͰສԁҎ্ٻ ͞Εͨྫɾɾɾ
18"࣮ࡍͲ͏ͳͷʁ w"OESPJEͰωΠςΟϒΞϓϦʹ͍ۙ͜ͱ͕Մೳ wJ04ͷ͔Β18"ରԠ wJ04Ͱϓογϡ௨ະରԠ wΞΠίϯͷόοδදࣔͰ͖ͳ͍ wϒϥβͷઃఆͰ௨0''ʹͰ͖Δ w·ͩ·ͩωΠςΟϒΞϓϦ͕ඞཁͦ͏ wݸਓతʹࠓޙʹେ͍ʹظʂʂ
ൃද༰ΞυϕϯτΧϨϯμʔͰ Nuxt.js Advent Calendar 2018 Vue.js Advent Calendar 2018 ˞༰มߋͷՄೳੑ͋Γ
EJ⒎FBTZͰ ҎԼͷΑ͏ͳਓࡒΛaେืूதʂʂ ϑϩϯτΤϯυΤϯδχΞ ᶃ ٕज़ྗͰੈքதͷΉ͔͍ͣ͠Λ؆୯ʹ͢Δ σβΠφʔ ᶄ σβΠϯྗͰੈքதͷΉ͔͍ͣ͠Λ؆୯ʹ͢Δ
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠