LoginSignup
1
0

More than 3 years have passed since last update.

QR忘れ物アプリ (4) ユーザー設定確認・変更ページ [Vue,Vuetify,Firebase]

Last updated at Posted at 2021-04-22

はじめに

構成
1. 環境構築: https://qiita.com/rayan/items/5d04ee2ca7860c220dec
2. ログインページ: https://qiita.com/rayan/items/1f0576395b9727635461
3. メニュー: https://qiita.com/rayan/items/3645506cdb10512fd87c
4. ユーザー設定確認・変更ページ: 今回

GitHubリポジトリ

準備中

省略表現

RTDB: Realtime Database

操作するファイル

  • src
    • router
      • index.js
    • mixins
      • DatabaseOps.js
    • views
      • UserPreferences.vue

src/views/UserPreferences.vue

ユーザー設定確認・変更ページの要素。各設定事項をlistの要素として格納している。

  • @change="formSubmit"でチェックボックス、選択要素が変更されたときにformSubmitを呼び出す。
    • formSubmitではv-modelに設定されている値をvaluesに格納し、RTDBのuserPreferencesの値を更新する。
<template>
  <div>
    <Header :title="title"/>
    <v-card class="overflow-hidden">
      <v-list-item-group
        v-model="selectedItem"
        color="primary"
      >
        <v-list-item
          v-for="(preference, i) in preferences"
          :key="i"
        >
          <v-checkbox
            v-if="preference.type == 'checkbox'"
            v-model="preference.value"
            :label="preference.text"
            @change="formSubmit"
          ></v-checkbox>
          <v-select
            v-if="preference.type == 'select'"
            v-model="preference.value"
            :items="preference.values"
            :label="preference.text"
            @change="formSubmit"
          ></v-select>
        </v-list-item>
      </v-list-item-group> 
    </v-card>
  </div>
</template>

<script>
import Header from '@/components/Header'
import DatabaseOps from '@/mixins/DatabaseOps'

export default {
  name: "UserPreferences",
  data: () => ({
    preferences: [
      { text: 'Notify when link is accessed', value: false, type: 'checkbox'},
      { text: 'Notification for items that are not lost', value: true, type: 'checkbox'},
      { text: 'Where to notify', values: ['email', 'app'], value: 'email', type: 'select'},
    ],
    title: 'User Preferences'
  }),
  components: {
    Header
  },
  methods: {
    formSubmit() {
      var values = {
        'notifyAtLinkOpen': this.preferences[0].value,
        'notifyNotLostItem': this.preferences[1].value,
        'whereToNotify': this.preferences[2].value
      };
      this.setUserPreferences(values);
    }
  },
  mixins: [DatabaseOps]
};
</script>

mixins/DatabaseOps.js

後に用いるメソッドも今回追加する。

export default {
    methods: {
        // User Credentials
        async getUserCredentials() {
            return firebase.database().ref('userCredentials/'+this.$userId).get().then((snapshot) => {
                return snapshot.val();
            }); // return promise
        },
        addUserCredentials(data) {
            firebase.database().ref('userCredentials/'+this.$userId).set(data);
        },
        setUserCredentials(data) {
            firebase.database().ref('userCredentials/'+this.$userId).set(data);
        },

        // User Preferences
        async getUserPreferences() {
            return firebase.database().ref('userPreferences/'+this.$userId).get().then((snapshot) => {
                return snapshot.val();
            }); // returns promise
        },
        initUserPreferences() {    
            var data = {
                'notifyAtLinkOpen': false,
                'notifyNotLostItem': true,
                'whereToNotify': 'email'
            };
            firebase.database().ref('userPreferences/'+this.$userId).set(data);
        },
        setUserPreferences(data) {
            firebase.database().ref('userPreferences/'+this.$userId).set(data);
        },

        // ItemIds
        async getItemIds(itemId) {
            return firebase.database().ref('itemIds/'+itemId).get().then((snapshot) => {
                return snapshot.val();
            }); // returns promise
        },
        setItemIds(itemId) {
            firebase.database().ref('itemIds/'+itemId).set(this.$userId);
        },

        // Items
        async getItems(itemId) {
            return firebase.database().ref('items/'+this.$userId+'/'+itemId).get().then((snapshot) => {
                return snapshot.val();
            }); // returns promise
        },
        async getAllItems() {
            return firebase.database().ref('items/'+this.$userId).orderByKey().once('value').then((snapshot) => {
                var data = [];
                snapshot.forEach((childSnapshot) => {
                    var key = childSnapshot.key; // timestamp
                    var childData = childSnapshot.val(); // data for item
                    childData.itemId = key;
                    data.push(childData); 
                });
                return data;
            }); 
        },
        setItems(itemId, data) {
            firebase.database().ref('items/'+this.$userId+'/'+itemId).set(data);
        },
        updateItems(itemId, data) {
            firebase.database().ref('items/'+this.$userId+'/'+itemId).update(data);
        },
        pushItems(data) {
            var itemId = firebase.database().ref('items/'+this.$userId).push(data).key;
            return itemId;
        },

        // Messages
        async getMessages(messageId) {
            return firebase.database().ref('messages/'+this.$userId+'/'+messageId).get().then((snapshot) => {
                return snapshot.val();
            }); // return promise
        },
        setMessages(messageId, data) {
            firebase.database().ref('messages/'+this.$userId+'/'+messageId).set(data);
        },
        pushMessages(data) {
            var messageId = firebase.database().ref('messages/'+this.$userId).push(data).key;
            return messageId;
        }
    }
}

router/index.js

新しくつくったUserPreferencesページの情報を追加する。

import Vue from "vue";
import VueRouter from "vue-router";

Vue.use(VueRouter);

const routes = [
  {
    path: "*",
    redirect: "/"
  },
  {
    path: "/mainMenu",
    name: "MainMenu",
    meta: { requiresAuth: true },
    component: () =>
      import("@/views/MainMenu.vue"),
  },
  {
    path: "/userPreferences",
    name: "UserPreferences",
    meta: { requiresAuth: true },
    component: () =>
      import("@/views/UserPreferences.vue"),
  },
  {
    path: "/",
    name: "Authentication",
    component: () =>
      import("@/views/Authentication.vue"),
  },
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
});

router.beforeEach((to, from, next) => {
  let requiresAuth = to.matched.some(record => record.meta.requiresAuth)
  let currentUser = firebase.auth().currentUser
  if (requiresAuth) { // if this page requires auth, redirect to auth page
    if (!currentUser) {
      next({
        path: '/',
        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    next() // this is required
  }
})

export default router;

Build

  • ビルドし、動作をテストする。動作のテストにはFirebase Emulatorが必要であるため、起動する。
npm run build
firebase emulators:start
  • dist/index.htmlをブラウザで閲覧する。ログイン後UserPreferencesページに移動する。
  • 設定を変更する。
  • RTDBデータベースを見てUserPreferencesが入力に応じて変化していることを確認する。

次回

アイテム登録ページ

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0