Is it possible to bring the “user” object to the “

2019-08-31 09:28发布

问题:

This question already has an answer here:

  • Retrieve String out of addValueEventListener Firebase 3 answers

I am trying to define a ref in vuefire to firebase path that depends on the current User. Is it possible to bring the "user" object to the "top level" and access it from outside the "on.AuthSateChanged(user => .... }" ?

firebase-config.js

 import * as firebase from "firebase";

var config = {
    apiKey: "XXXXXX",
    authDomain: "XXXXXX.firebaseapp.com",
    databaseURL: "https://XXXXXX.firebaseio.com",
    projectId: "XXXXXX",
    storageBucket: "XXXXXX.appspot.com",
    messagingSenderId: "XXXXXX"
};
firebase.initializeApp(config)
export default !firebase.apps.length ? firebase.initializeApp(config) : firebase;


firebase.auth().onAuthStateChanged((user) => {
    if (user) {
        let userRef = firebase.database().ref('users').child(user.uid);
        let buildingsRef = userRef.child('buildings');
    }
  })();
console.log(buildingsRef); //returning undefined=    

export const db = firebase.database(); 
export const usersRef = db.ref('users');
export const buildingsRef = db.ref('users'+ "/" +buildingsRef)
// I will deal with this later
// export const deptsRef = db.ref('depts');
// export const roomsRef = db.ref('rooms'); 

app.vue

<template>
  <div id="app" class="section">   
    <main>
      <router-view id="main" ></router-view>
    </main>
  </div>
</template>

<script>
import firebase from './firebase-config';
import { buildingsRef } from './firebase-config';
import { deptsRef } from './firebase-config'; 

export default {
  name: 'app',
  data () {
    return {
    }
  },
}
</script>

buildingadd.vue (component)

<template>
  <div class="building">
    <div id="title">
      <h1>{{ initialmsg }}</h1>
    </div>  
    <form id="form" class="form-inline" v-on:submit.prevent="addBuilding">
      <div class="form-group">     
        <p><span> Name: </span><input class="input typename" type="text" placeholder="type name" v-model="newBuilding.name"></p>
      </div>
      <div class="form-group">            
        <p><input type="text" id="buildingAddress" class="form-control" placeholder="Address" v-model="newBuilding.address"></p>
      </div>
      <div class="form-group">            
        <p><textarea id="buildingComments" class="form-control text" cols="40" rows ="6" placeholder="Comments (optional)" v-model="newBuilding.comments"></textarea></p>
      </div>               
      <!-- <button id="addButton" class="button">Add New Space</button> -->
      <router-link  to="/buildings"><button @click="addBuilding" :disabled="!formIsValid">Save</button></router-link>
    </form>
    <!-- <button type="submit" id="updateButton" class="button is-primary"  @click.prevent="updateSpace(newSpace), show = !show" >UPDATE </button>  -->
  </div>
</template>

<script>
import firebase from '../firebase-config';
import { buildingsRef } from '../firebase-config';
import { usersRef } from '../firebase-config';

export default {
  firebase() { 
    return {
    buildings:  buildingsRef,
    users: usersRef,
    }
  },
  name: 'buildingsadd',
  data () {
    return {
      initialmsg: "Add building's details:",
      newBuilding: {
        name: '',
        address: '',
        comments: '',
        ownerID: '',
      }
    }
  },
  methods: {
    setUser() {
        this.$store.dispatch('setUser');
      },
    addBuilding: function () {
      let userId = firebase.auth().currentUser.uid;
      let buildingKey = buildingsRef.push().key
      this.newBuilding.ownerID = userId;
      buildingsRef.child(buildingKey).set(this.newBuilding);
      usersRef.child(userId).child('isAdmin').child(buildingKey).set(true);
    },    
  },
  computed: {
    formIsValid() {
      return this.newBuilding.name !== '';
    },    
  },
}

Alternatively an answer to this question would also solve my specific problem. How to constrain read/write rules to the users that create the nodes while keeping this structure?

I would really appreciate your help. thanks!

回答1:

Simply adding it to the window object will do.

window.userRef = userRef;

e.g.

firebase.auth().onAuthStateChanged(user => {
  if (user) {
    let userRef = firebase.database().ref('users').child(user.uid);
    window.userRef = userRef;
    let buildingsRef = userRef.child('buildings');
    // userRef returns the user uid 
  }
});

console.log(userRef); // no longer undefined only if this is called after `onAuthStateChanged` response. Thanks @EmileBergeron