前回、シナリオゲームが手軽に作れるティラノスクリプトに
強引にVue.jsを入れることをやりましたが。
次は、、、Firebaseを入れたい!!
やはり本格的なWebアプリケーションを作るためにはデータベースとの連携は必須。
そしてFirebaseのFirestoreならとても扱いやすい。
もし、Firebaseとティラノスクリプトが掛け算できるなら
どんなものでも作れそうですよね。
それではいきましょう!!
Firebaseを初期化する
例によって強引にindex.htmlにscriptタグを埋め込みます。
firestoreとauthを使いたかったのでそれも入れています。
first.ksなどで初期化します。
;Firebase [iscript] console.log("Init firebase"); // Initialize Cloud Firestore through Firebase firebase.initializeApp({ apiKey: 'xxxxx', authDomain: 'yyyyy.firebaseapp.com', projectId: 'zzzzzzz' }); f.db = firebase.firestore(); f.auth = firebase.auth(); [endscript]
初期設定をして
ティラノスクリプトのゲーム変数(f)にdbとauthを登録しておきます。
呼び出す!
こんな感じで、例えばscene1.ksのiscriptタグの中で
firebase authenticationのユーザログイン情報を取得したり。
;Firebase [iscript] f.auth.onAuthStateChanged(user => { if (user) { f.displayName = user.displayName; f.email = user.email; f.uid = user.uid; } }); [endscript]
こんな感じで、firestoreの任意のコレクションからデータを取ったりできます
;Firebase [iscript] (async () => { let query = await f.db.collection("contact") .orderBy("created","asc").limit(20); const snapShot = await query.get(); const datas = snapShot.docs.map(doc => { return doc.data(); }); console.log(datas); })(); [endscript] f.msg の内容 : [emb exp="f.msg"][p]
この例では、contactコレクションから20個データを取って来て
メッセージに1つ目の内容を表示しています
質問ですが、awaitが機能しない場合は、どうしたらいいでしょうか
今は[wait time=1000]で誤魔化したのですが、もし読み込み時間が一秒以上なら、データは読み込まず、undefinedになっていまう…
解決策を教えていただけますでしょうか。
コードは以下です:
;Firebase
[iscript]
(async () => {
let db = firebase.firestore();
let docRef = await f.db.collection(‘user’).doc(‘test’);
await docRef.get().then(function(doc) {
if (doc.exists) {
f.money = doc.data().money;
}
}).catch(function(error) {
console.log(“Error getting document:”, error);
});
})();
[endscript]
[wait time=1000]
f.money の内容 : [emb exp=”f.money”][p]
見たところawaitとthen()が共存しちゃってますので、どちらかにする必要があります
あと、コレクションではなくドキュメントを取ってきているようなので次のような感じかと
then()系なら
こう書きますし
docRef.get().then(function(doc) {
xxx
}).catch(function(error) {
xxx
});
await使うなら↓みたいな形になります。
(async () => {
var doc = await docRef.get();
if(doc.eixsts){
xxx
}
}()
ご返信ありがとうございます。
awaitだけ残してみると、だめでした…
でもalertからはちゃんとデータを取り出しだのですが、いつもawaitは無視されて、シナリオが進んだ途中でalertが出てくるって感じ…
訂正したコードは以下です:
[iscript]
(async () => {
let db = firebase.firestore();
let docRef = await f.db.collection(‘user’).doc(‘test’);
let doc = await docRef.get();
if (doc.exists) {
f.money = doc.data().money;
alert(f.money);
}
})();
[endscript]
;alertの前に執行されます
f.money の内容 : [emb exp=”f.money”][p]
そうなんですね。
その挙動を見るとおそらくiscriptタグ内ではawaitはちゃんと動くようですが。
[endscript]以降までは及ばないということのようですね。
ちょっとリアルタイムな値の取得は厳しそうですので、利用したいタイミングの5秒前くらいにあらかじめ非同期で取得してお区など工夫が必要な気がします
そうなんですか
今は無限ループで無理やりシナリオの動きを一旦停止していますが、解決策はこれしかないか…
ご協力ありがとうございました!
*await1
[wait time=100]
[if exp=”f.money == undefined”]
[jump target=*await1]
[endif]