Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Nuxt.jsとFirebaseで爆速でPWA対応Webアプリを開発した話
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
TakeshiNishi
December 08, 2018
Programming
1.4k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Nuxt.jsとFirebaseで爆速でPWA対応Webアプリを開発した話
フロントエンドカンファレンス福岡の発表スライドです。
NuxtとFirebaseを使って、PWA対応のリアルタイムWebチャットアプリケーションを開発した話をします。
TakeshiNishi
December 08, 2018
More Decks by TakeshiNishi
See All by TakeshiNishi
LT駆動開発 - 話題のChatGPTで何か作る
takec24
0
210
成長ステージ別のスタートアップ集結!「事業の魅力とチームの本音」
takec24
0
180
Developing FLAPTALK by Firebase
takec24
1
460
NuxtCompositionAPIとFirebaseの話
takec24
1
560
コロナ禍でもリモート案件を途切れさせない! 案件の獲得方法とリモート案件の進め方。
takec24
0
420
フロントエンドエンジニアのためのFirebaseサーバーレス開発徹底解説
takec24
0
1.4k
スタートアップで働くというエンジニアキャリア
takec24
1
1.3k
人生を変えた炎上ブロジェクト
takec24
0
1.7k
好きなことを選び続けたら代表取締役CTOになりました。
takec24
3
1.4k
Other Decks in Programming
See All in Programming
Snowflake Openflow Connector利用の勘所 / 20261024developersio2026tokyo-snowflake-openflow
kasacchiful
PRO
0
280
Python Lambdaにおけるテストしやすい設計とAI支援の活用 / Designing Testable Python Lambda Functions with AI
kitano_yuichi
1
290
Vue.jsで作る空間解析アプリとCapacitorプラグインのData Bridge
hal_spidernight
1
160
AI-Powered Domain-Driven Design
ziobrando
0
390
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.8k
Kawaiicon: Kubernetes, it's no longer cool, but let's secure it anyway!
barnbarn
0
100
全ての永続トークンを、生まれる前に消し去りたい!
sylph01
3
1.7k
Spec-driven Development with AI
simas
PRO
0
2.2k
선언형 햅틱 라이브러리 진동을 소개합니다
l2hyunwoo
1
280
自作Discord音声botをLambda MicroVMsに移行した話 / Migrating My Discord Voice Bot to Lambda MicroVMs
akihisaikeda
1
280
Next.js: The final boss of Web Performance
guaca
0
380
学びを記事・スライド・Xへ高速展開する― AI-assisted Learning Loopで回すコンテンツ生成術
ochtum
0
190
Featured
See All Featured
The Pragmatic Product Professional
lauravandoore
37
7.5k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
77k
The untapped power of vector embeddings
frankvandijk
2
2k
Building Better People: How to give real-time feedback that sticks.
wjessup
371
20k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
320
Color Theory Basics | Prateek | Gurzu
gurzu
1
510
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1.1k
Context Engineering - Making Every Token Count
addyosmani
9
1.3k
Product Roadmaps are Hard
iamctodd
55
13k
Accessibility Awareness
sabderemane
1
290
What the history of the web can teach us about the future of AI
inesmontani
PRO
2
790
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
670
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େืूதʂʂ ϑϩϯτΤϯυΤϯδχΞ ᶃ ٕज़ྗͰੈքதͷΉ͔͍ͣ͠Λ؆୯ʹ͢Δ σβΠφʔ ᶄ σβΠϯྗͰੈքதͷΉ͔͍ͣ͠Λ؆୯ʹ͢Δ
͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠