Nativescript Vue:Firebase/Firestore与Nativescript插件Firebase混淆

Nativescript Vue:Firebase/Firestore与Nativescript插件Firebase混淆,firebase,google-cloud-firestore,nativescript,nativescript-vue,Firebase,Google Cloud Firestore,Nativescript,Nativescript Vue,我知道这只是我在这一点上缺乏理解,但我不知道还有什么地方可以转向,我觉得我需要一个ELI5在这一点上。现在我没有发现任何错误,但我也不确定要朝哪个方向完成下一个问题/任务 这是我第一次用Firebase开发Nativescript应用程序。我能够按照这篇有用的文章()通过Firebase的身份验证,但现在我尝试使用Firestore访问我的收藏,以便显示其中的数据文档。Home.vue是一个选项卡式布局(后面有一些额外的代码),在这些选项卡式视图中,我正试图添加功能来CRUD firestore

我知道这只是我在这一点上缺乏理解,但我不知道还有什么地方可以转向,我觉得我需要一个ELI5在这一点上。现在我没有发现任何错误,但我也不确定要朝哪个方向完成下一个问题/任务

这是我第一次用Firebase开发Nativescript应用程序。我能够按照这篇有用的文章()通过Firebase的身份验证,但现在我尝试使用Firestore访问我的收藏,以便显示其中的数据文档。Home.vue是一个选项卡式布局(后面有一些额外的代码),在这些选项卡式视图中,我正试图添加功能来CRUD firestore数据

我目前正在处理两个页面,nativescript插件firebase()的CloudFireStore页面和Google firebase文档()

我觉得我现在没有正确初始化Firebase/Firestore,为什么这对我来说很难理解,我只是不知道。在这一点上,任何指导或帮助都将不胜感激

  • 我想知道的一件事是,即使我使用了nativescript插件firebase插件,我是否仍然必须添加我唯一的初始化代码。如果是这样,我觉得我应该有一个单独的*.js文件来满足我所有的Firebase需求。任何建议都将不胜感激
app.js


import VueDevtools from 'nativescript-vue-devtools';
import Vue from "nativescript-vue";
import LoginPage from './components/LoginPage';

//import DashboardPage from "./components/DashboardPage.vue";

import FloatLabel from './components/FloatLabel';

Vue.component('FloatLabel', FloatLabel);

Vue.use(VueDevtools)

// Initialize Firebase
var firebase = require("nativescript-plugin-firebase");

//Addig the code on the line below makes the debugger crrash (unaccepted app.js)
var db = require("nativescript-plugin-firebase/app/firestore");

firebase.init({}).then((instance) => {
    console.log("[*] Firebase was successfully initialised");
}, (error) => {
console.log("[*] Huston we've an initialization error: " + error);
});

//var db = require("firebase/firestore"); 
// Integrate Firestore
//var bulkyCollection = firebase.firestore().collection("bulktrash")

//const backendService = new BackendService();
//Vue.prototype.$backendService = backendService;

new Vue({
    render: h => h('frame', [h(LoginPage)])
  }).$start()

LoginPage.vue


<template>
  <Page>
    <FlexboxLayout class="page">
      <StackLayout class="form">
        <Image class="logo" src="~/images/logo.png" />
        <Label class="header" text="BULKY" />

        <StackLayout class="input-field" marginBottom="25">
          <TextField class="input" hint="Email" keyboardType="email" autocorrect="false" autocapitalizationType="none" v-model="user.email"
           returnKeyType="next" @returnPress="focusPassword" fontSize="18" />
          <StackLayout class="hr-light" />
        </StackLayout>

        <StackLayout class="input-field" marginBottom="25">
          <TextField ref="password" class="input" hint="Password" secure="true" v-model="user.password" :returnKeyType="isLoggingIn ? 'done' : 'next'"
           @returnPress="focusConfirmPassword" fontSize="18" />
          <StackLayout class="hr-light" />
        </StackLayout>

        <StackLayout v-show="!isLoggingIn" class="input-field">
          <TextField ref="confirmPassword" class="input" hint="Confirm password" secure="true" v-model="user.confirmPassword" returnKeyType="done"
           fontSize="18" />
          <StackLayout class="hr-light" />
        </StackLayout>

        <Button :text="isLoggingIn ? 'Log In' : 'Sign Up'" @tap="submit" class="btn btn-primary m-t-20" />
        <Label v-show="isLoggingIn" text="Forgot your password?" class="login-label" @tap="forgotPassword" />
      </StackLayout>

      <Label class="login-label sign-up-label" @tap="toggleForm">
            <FormattedString>
              <Span :text="isLoggingIn ? 'Don’t have an account? ' : 'Back to Login'" />
              <Span :text="isLoggingIn ? 'Sign up' : ''" class="bold" />
            </FormattedString>
          </Label>
    </FlexboxLayout>
  </Page>
</template>
<script>
// Firebase authenticates users.
import firebase from "nativescript-plugin-firebase";
import Home from "./Home";

// App did not ccrash, but it didnnt seem right either
// const db = firebase.firestore;

//App crahses with line belows...iunno
//const bulkyCollection = firebase.firestore().collection("bulktrash");

const userService = {
  async register(user) {
    return await firebase.createUser({
      email: user.email,
      password: user.password
    });
  },
  async login(user) {
    return await firebase.login({
      type: firebase.LoginType.PASSWORD,
      passwordOptions: {
        email: user.email,
        password: user.password
      }
    });
  },
  async resetPassword(email) {
    return await firebase.resetPassword({
      email: email
    });
  }
};
// A stub for the main page of your app. In a real app you’d put this page in its own .vue file.
const HomePage = {
  template: `
  <Page>
        <Label class="m-20" textWrap="true" text="You have successfully authenticated. This is where you build your core application functionality."></Label>
  </Page>
  `
};

var LoadingIndicator = require("nativescript-loading-indicator")
  .LoadingIndicator;
var loader = new LoadingIndicator();

export default {
  data() {
    return {
      isLoggingIn: true,
      user: {
        email: "yao@ming.com",
        password: "basbhat01",
        confirmPassword: "basbhat01"
      }
    };
  },
  methods: {
    toggleForm() {
      this.isLoggingIn = !this.isLoggingIn;
    },
    submit() {
      if (!this.user.email || !this.user.password) {
        this.alert("Please provide both an email address and password.");
        return;
      }
      loader.show();
      if (this.isLoggingIn) {
        this.login();
      } else {
        this.register();
      }
    },
    login() {
      userService
        .login(this.user)
        .then(() => {
      loader.hide();
      this.$navigateTo(Home);          
        })
        .catch(err => {
          console.error(err);
          loader.hide();          
          this.alert(err);
        });
    },
    register() {
      var validator = require("email-validator");
      if (!validator.validate(this.user.email)) {
        loader.hide();
        this.alert("Please enter a valid email address.");
        return;
      }
      if (this.user.password != this.user.confirmPassword) {
        loader.hide();
        this.alert("Your passwords do not match.");
        return;
      }
      if (this.user.password.length < 6) {
        loader.hide();
        this.alert("Your password must at least 6 characters.");
        return;
      }
      userService
        .register(this.user)
        .then(() => {
          loader.hide();
          this.alert("You may now login.");
          this.isLoggingIn = true;
        })
        .catch(err => {
          console.error(err);
          loader.hide();
          this.alert(err);
        });
    },
    forgotPassword() {
      prompt({
        title: "Forgot Password",
        message:
          "Enter the email address you used to register for APP NAME to reset your password.",
        inputType: "email",
        defaultText: "",
        okButtonText: "Ok",
        cancelButtonText: "Cancel"
      }).then(data => {
        if (data.result) {
          loader.show();
          userService
            .resetPassword(data.text.trim())
            .then(() => {
              loader.hide();
              this.alert(
                "Your password was successfully reset. Please check your email for instructions on choosing a new password."
              );
            })
            .catch(() => {
              loader.hide();
              this.alert(err);
            });
        }
      });
    },
    focusPassword() {
      this.$refs.password.nativeView.focus();
    },
    focusConfirmPassword() {
      if (!this.isLoggingIn) {
        this.$refs.confirmPassword.nativeView.focus();
      }
    },
    alert(message) {
      return alert({
        title: "Account Created!",
        okButtonText: "OK",
        message: message
      });
    }
  }
};
</script>

<style scoped>
  .page {
    align-items: center;
    flex-direction: column;
  }

  .form {
    margin-left: 30;
    margin-right: 30;
    flex-grow: 2;
    vertical-align: middle;
  }

  .logo {
    margin-bottom: 12;
    height: 90;
    font-weight: bold;
  }

  .header {
    horizontal-align: center;
    font-size: 25;
    font-weight: 600;
    margin-bottom: 70;
    text-align: center;
    color: #D51A1A;
  }

  .input-field {
    margin-bottom: 25;
  }

  .input {
    font-size: 18;
    placeholder-color: #A8A8A8;
  }

  .input-field .input {
    font-size: 54;
  }

  .btn-primary {
    height: 50;
    margin: 30 5 15 5;
    background-color: #D51A1A;
    border-radius: 5;
    font-size: 20;
    font-weight: 600;
    color: #FFFFFF;
  }

  .login-label {
    horizontal-align: center;
    color: #A8A8A8;
    font-size: 16;
  }

  .sign-up-label {
    margin-bottom: 20;
  }

  .bold {
    color: #000000;
  }
</style>


//Firebase对用户进行身份验证。
从“nativescript插件firebase”导入firebase;
从“/Home”导入主页;
//应用程序并没有出现问题,但它似乎也不正确
//const db=firebase.firestore;
//下面有行的应用程序crahses…iunno
//const bulkyCollection=firebase.firestore().collection(“bulktrash”);
常量用户服务={
异步寄存器(用户){
return wait firebase.createUser({
电子邮件:user.email,
密码:user.password
});
},
异步登录(用户){
return wait firebase.login({
类型:firebase.LoginType.PASSWORD,
密码选项:{
电子邮件:user.email,
密码:user.password
}
});
},
异步重置密码(电子邮件){
return wait firebase.resetPassword({
电邮:电邮
});
}
};
//应用程序主页的存根。在真正的应用程序中,您可以将此页面放在自己的.vue文件中。
const主页={
模板:`
`
};
var LoadingIndicator=require(“nativescript加载指示符”)
.装载指示器;
var loader=new LoadingIndicator();
导出默认值{
数据(){
返回{
伊斯洛金:是的,
用户:{
电子邮件:“yao@ming.com",
密码:“basbhat01”,
确认密码:“basbhat01”
}
};
},
方法:{
toggleForm(){
this.islogging=!this.islogging;
},
提交(){
如果(!this.user.email | |!this.user.password){
此警报(“请同时提供电子邮件地址和密码”);
返回;
}
loader.show();
如果(此为IsLogging){
this.login();
}否则{
这是register();
}
},
登录(){
用户服务
.login(此.user)
.然后(()=>{
loader.hide();
这是$navigateTo(主页);
})
.catch(错误=>{
控制台错误(err);
loader.hide();
这个。警报(err);
});
},
寄存器(){
var validator=要求(“电子邮件验证器”);
如果(!validator.validate(this.user.email)){
loader.hide();
此.alert(“请输入有效的电子邮件地址”);
返回;
}
if(this.user.password!=this.user.confirmPassword){
loader.hide();
此.alert(“您的密码不匹配”);
返回;
}
if(this.user.password.length<6){
loader.hide();
此.alert(“您的密码必须至少包含6个字符”);
返回;
}
用户服务
.register(此.user)
.然后(()=>{
loader.hide();
此.alert(“您现在可以登录”);
this.isloggin=true;
})
.catch(错误=>{
控制台错误(err);
loader.hide();
这个。警报(err);
});
},
放弃密码(){
提示({
标题:“忘记密码”,
信息:
“输入用于注册APP NAME以重置密码的电子邮件地址。”,
输入类型:“电子邮件”,
defaultText:“”,
Ok按钮文字:“Ok”,
cancelButtonText:“取消”
})。然后(数据=>{
if(data.result){
loader.show();
用户服务
.reset密码(data.text.trim())
.然后(()=>{
loader.hide();
这是警报(
“您的密码已成功重置。有关选择新密码的说明,请查看您的电子邮件。”
);
})
.catch(()=>{
loader.hide();
这个。警报(err);
});
}
});
},
focusPassword(){
这是.$refs.password.nativeView.focus();
},
FocusConfigPassword(){
如果(!this.isloggin){
这是.$refs.confirmPassword.nativeView.focus();
}
},
警报(信息){
返回警报({
标题:“已创建帐户!”,
OK按钮文字:“OK”,
信息:信息
});
}
}
};
.第页{
对齐项目:居中;
弯曲方向:立柱;
}
.表格{
左边距:30;
右边距:30;
柔性生长:2;
垂直对齐:中间对齐;
}
.标志{
保证金底部:12;
身高:90;
字体大小:粗体;
}
.标题{
水平对齐:居中对齐;
字号:25 ;;
字号:600;
保证金底部:

<template>
    <Page class="page">

        <ActionBar 
            title=" " flat="true" v-bind:class="{ completed: activeTabIndex == 1 }">
        </ActionBar>

        <TabView :selectedIndex="activeTabIndex" @selectedIndexChange="onTabChange">
            <TabViewItem title="Requests">
                <GridLayout rows="auto, auto, *">
                    <Label row="0" text="Requests" class="header" />

                    <TextField row="1" ref="taskInput" v-model="textFieldValue"
                        hint="Enter text..." returnKeyType="done" @returnPress="onReturnPress" />

                    <ListView row="2" class="list-group" for="todo in todos">
                        <v-template>
                            <GridLayout columns="auto, *">
                                <Label col="0" v-on:tap="onTodoCircleTap(todo)"
                                    text=" " />
                                <Label col="1" v-on:tap="onTodoItemTap(todo)"
                                    :text="todo.name" textWrap="true" />
                            </GridLayout>
                        </v-template>
                    </ListView>

                </GridLayout>
            </TabViewItem>
            <TabViewItem title="History">
                <GridLayout rows="auto, *">
                    <Label row="0" text="History" class="header" />

                    <ListView row="1" class="list-group" for="done in dones"
                        @itemTap="onItemTap">
                        <v-template>
                            <GridLayout columns="auto, *">
                                <Label col="0" text="✓" />
                                <Label col="1" :text="done.name" textWrap="true" />
                            </GridLayout>
                        </v-template>
                    </ListView>
                </GridLayout>
            </TabViewItem>
            <TabViewItem title="Profile">
                <GridLayout rows="auto, auto, *">
                    <Label row="0" text="Profile" class="header" />

                    <TextField row="1" ref="taskInput" v-model="textFieldValue"
                        hint="+ New request" returnKeyType="done" @returnPress="onReturnPress" />

                    <ListView row="2" class="list-group" for="todo in todos">
                       <v-template>

                            <GridLayout columns="auto, *, auto, *"
                                rows="auto, auto" class="list-entry">
                                <!-- Circle Icon 
                                <Label col="0" row="0" v-on:tap="onTodoCircleTap(todo)" class="circle" text=" " />             -->

                                <!-- Formated Requested Date -->
                                <Label col="0" row="0"
                                    v-on:tap="onTodoItemTap(todo)"
                                    textWrap="true">
                                    <FormattedString ios.fontFamily="system">
                                        <Span class="fas t-18"></Span>
                                        <Span text=" Requested: "
                                            color="gray">
                                        </Span>
                                        <Span :text=" todo.requested"> </Span>
                                    </FormattedString>
                                </Label>
                                <!-- Formated Pickup Date -->
                                <Label col="0" row="1"
                                    v-on:tap="onTodoItemTap(todo)"
                                    textWrap="true">
                                    <FormattedString ios.fontFamily="system">
                                        <Span class="fas t-18"></Span>
                                        <Span text=" Pickup: " color="gray">
                                        </Span>
                                        <Span :text=" todo.pickup"> </Span>
                                    </FormattedString>
                                </Label>
                                <!-- Formated Bulk Type -->
                                <Label col="2" row="0"
                                    v-on:tap="onTodoItemTap(todo)"
                                    textWrap="true">
                                    <FormattedString ios.fontFamily="system">
                                        <Span class="fas t-18"></Span>
                                        <Span text=" Type: " color="gray">
                                        </Span>
                                        <Span :text=" todo.type"> </Span>
                                    </FormattedString>
                                </Label>

                                <!-- Formated Bulk Status -->
                                <Label col="2" row="1"
                                    v-on:tap="onTodoItemTap(todo)"
                                    textWrap="true">

                                    <FormattedString ios.fontFamily="system">
                                        <Span class="fas t-18"></Span>
                                        <Span text=" Status: " color="gray">
                                        </Span>
                                        <Span :text=" todo.status"> </Span>
                                    </FormattedString>

                                </Label>
                                <!-- Extra Label -->


                            </GridLayout>

                        </v-template>
                    </ListView>

                </GridLayout>
            </TabViewItem>

            <TabViewItem title="Add Requests">
                <!-- CREATE a Grid Layout with 5 (0, 1, 2, 3, 4) rows -->
                <GridLayout rows="auto, auto, auto, auto, auto">
                    <!-- ROW 0: Add Label "Add Request" -->
                    <Label row="0" text="New Request" class="header" />
                    <!-- ROW 1: Add Text Field "Request Type" -->
                    <TextField row="1" ref="taskInput" v-model="bulk.bulk_type"
                        hint="Request Type" returnKeyType="done" @returnPress="onReturnPress" />
                    <!-- ROW 2: Add Text Field "Request Name" -->
                    <TextField row="2" ref="taskInput" v-model="bulk.bulk_requestor"
                        hint="Pickup Date" returnKeyType="done" @returnPress="onReturnPress" />
                    <!-- ROW 3: Add Text Field "Description" -->
                    <TextField row="3" ref="taskInput" v-model="bulk.bulk_description"
                        hint="Description" returnKeyType="done" @returnPress="onReturnPress" />
                    <!-- ROW 4: Add Button "save" -->
                    <Button row="4" text="save" @tap="saveData" backgroundColor="green" class="btn btn-primary m-t-20" />

                </GridLayout>

            </TabViewItem>


        </TabView>
    </Page>
</template>

<script>
import firebase from "nativescript-plugin-firebase";
import LoginPage from "./LoginPage";



    export default {
        methods: {
            saveData() {
                db.collection("bulktrash").add(this.bulk)
                .then((docRef) => {
                    console.log("Document written with ID: ", docRef.id);
                })
                .catch(function(error) {
                    console.error("Error adding document: ", error);
                });
            },
            onTodoItemTap(item) {
                const index = this.todos.indexOf(item);
                action("What do you want to do with this task?", "Cancel", ["Mark completed", "Delete forever"]).then(result => {
                    console.log(result);
                    switch (result) {
                        case "Mark completed":
                            this.dones.unshift(item);
                            this.todos.splice(index, 1);
                            this.activeTabIndex = 1;
                            break;
                        case "Delete forever":
                            this.todos.splice(index, 1);
                            break;
                        case "Cancel" || undefined:
                            break;
                    }
                });
            },

            onTodoCircleTap(item) { 
                const index = this.todos.indexOf(item); 
                this.dones.unshift(item);
                this.todos.splice(index, 1);
                this.activeTabIndex = 1;
            },

            onReturnPress() {
                if (this.textFieldValue.trim() === "") {
                    this.$refs.taskInput.nativeView.focus();
                    return;
                }
                console.log("New task added: " + this.textFieldValue + ".");
                this.todos.unshift({
                    name: this.textFieldValue
                });
                this.textFieldValue = "";
            },

            onTabChange(tab) {
                this.activeTabIndex = tab.value;
            }
        },
/*         created() {
            db.collection("bulktrash").get().then(function(querySnapshot) {
            querySnapshot.forEach(function(doc) {
                // doc.data() is never undefined for query doc snapshots
                console.log(doc.id, " => ", doc.data());
            });
        });
        }, */

        data() {
            return {
                bulks: [],
                bulk: {
                    bulk_id:null,
                    bulk_type:null,
                    bulk_location:null,
                    bulk_zone: null,
                    bulk_description: null,
                    bulk_dnotes: null,
                    bulk_requestor: null,
                    bulk_phone: null,
                    bulk_email: null,
                    //bulk_requested: null,
                },
                todos: [{
                        name: "John Smith",
                        type: "Aluminum",
                        requested: "10/04/19",
                        pickup: "10/23/19",
                        status: "Pending"
                    },
                    {
                        name: "Christine Tarbone",
                        type: "Cardboard",
                        requested: "10/07/19",
                        pickup: "10/23/19",
                        status: "Pending"
                    },
                    {
                        name: "Jamie Trotter",
                        type: "Aluminum",
                        requested: "10/02/19",
                        pickup: "10/12/19",
                        status: "Pending"
                    },
                    {
                        name: "Chris Evans",
                        type: "Electronics",
                        requested: "10/04/19",
                        pickup: "10/23/19",
                        status: "Pending"
                    }
                ],
                dones: [],
                bulkRequestType: "",
                textFieldValue2: "",
                textFieldValue3: "",
                activeTabIndex: 0
            };
        }
    };
</script>
<style scoped>
    ActionBar {
        background-color: #35495e;
    }

    .header {
        background-color: #35495E;
        color: white;
        font-size: 34;
        font-weight: 600;
        padding: 0 15 15 15;
        margin: 0;
    }

    .completed {
        background-color: #42B883;
    }

    .reminder {
        background-color: #42B883;
    }

    .logo {
        margin-bottom: 12;
        height: 90;
        font-weight: bold;
        background-color: #35495e;
    }

    TextField {
        width: 100%;
        font-size: 17;
        color: black;
        placeholder-color: #C1C1C1;
        padding: 17;
        border-width: 0 0 1 0;
        border-color: #E0E0E0;
    }

    .list-entry {
        padding: 0 15;
        color: #42B883;
    }

    .circle {
        width: 30;
        height: 30;
        padding: 0;
        color: #42B883;
        font-size: 25;
        border-color: #42B883;
        border-width: 2;
        border-radius: 50;
    }

    .list-entry .circle {
        margin: 0 10 0 0;
    }

    .list-entry Label {
        font-weight: bold;
        font-size: 17;
        vertical-align: middle;
        padding: 17 0;
        margin: 0;
    }

    .list-entry-completed .circle {
        color: white;
        background-color: #42B883;
        text-align: center;
        padding: 0;
    }
</style>

import firebase from "nativescript-plugin-firebase";
import LoginPage from "./LoginPage";

import firestore from "nativescript-plugin-firebase/app/firestore";

const db = firebase.firestore;