Firebase / React:如果电子邮件尚不存在,请添加用户电子邮件记录

时间:2017-09-21 15:35:46

标签: reactjs firebase firebase-realtime-database

这个问题已经被多次询问和回答了,但在我看来,firebase已经发生了变化,大多数提供的答案都不再适用了,所以我再次回到这个简单的场景:我有一个表单,其中一个用户可以输入他的电子邮件然后,我正在创建一个新的firebase记录,例如:

-Ku_1ojtDA-3hVO6aN38
   email: "hello@world.com"

我主要担心的是避免在firebase中重复发送相同的电子邮件,因此我在尝试“获取”基础并在发布之前检查具有相同值的现有记录。到目前为止,这是我为此联系表单制作的组​​件:

import React, { Component } from 'react';
import * as firebase from 'firebase';

const config = {
  apiKey: "**************************************",
  authDomain: "***********.firebaseapp.com",
  databaseURL: "https://***********.firebaseio.com",
  projectId: "***********",
  storageBucket: "",
  messagingSenderId: "***********",
};


const database = firebase
  .initializeApp(config)
  .database()

const addLocation = data => database.ref().child('users').push(data, response => response);

const updateLocation = (id, data) => database.ref().child(`users/${id}`).update(data, response => response);

const actions = {
  addLocation,
  updateLocation,
};


class Contact extends Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    event.preventDefault();
    var email = this.state.value;
    // database.ref("users").orderByChild('email').equalTo(email).once("value", snapshot => {    
    database.ref().child("users").orderByChild('email').equalTo(email).once("value", snapshot => {
      const userEmail = snapshot.val();
      if (userEmail){
        console.log("user exists!");
      } else {
        addLocation({email: email});
      }
    });
    dataLayer.push({'event': 'emailAcquisition'});
  }


  render() {
    return (

            <form onSubmit={this.handleSubmit}>
              <div className="centerpanel is-mobile">
                <div className="leftpanel" id="email-field">
                  <p className="control has-icons-left">
                    <input className="input is-large" type="email" id="email-field" placeholder="Email" value={this.state.value} onChange={this.handleChange}  />
                    <span className="icon is-normal is-left">
                      <i className="fa fa-envelope"></i>
                    </span>
                  </p>
                </div>
                <div className="rightpanel" id="email-button">
                  <p className="control">
                    <input className="button is-primary is-large" type="submit" value="Submit" />
                  </p>
                </div>
              </div>
            </form>

    );
  }
}

export default Contact;

目前,我认为问题来自以下代码无法正常工作:

database.ref("users").orderByChild('email').equalTo(email).once(...)

对于noob问题,很抱歉,任何输入都表示赞赏。

2 个答案:

答案 0 :(得分:1)

检查任何引用中是否存在电子邮件或用户名或任何值的最佳和官方方法是使用其他节点来存储和复制电子邮件,例如如下所示:

+emails:
-------hello@world.com : true,
-------another@email.com: true

通过这种方式,您可以通过向email节点添加一次侦听器来轻松检查从{text}或任何内容中获取的emails变量的值是否存在,然后您将获得带有{{{ 1}}值如果电子邮件节点上不存在该电子邮件,则以下js示例已在我的应用程序上测试并运行:

null

您可以将电子邮件添加到重复节点,如下所示:

firebase.database().ref('emails/'+ email).once('value', function (dataSnapshot) {
if(dataSnapshot.val() !== null) { 
        console.log(dataSnapshot.val());
        //the email already exists
   }
else{
       //the  email is available
}

请注意,firebase.database().ref('emails/' + email).set(true); 变量是您的变量,其中包含您要检查其可用的电子邮件。
非规范化在firebase中是正常的,您必须按照在UI中使用它的方式构建数据。更多信息是here

答案 1 :(得分:1)

这是工作代码,问题是我试图阅读基础的方式:

 handleSubmit(event) {
    var userEmail = this.state.value;
    event.preventDefault();
    firebase.database().ref('/users').orderByChild("email").equalTo(userEmail).once('value').then(function(snapshot) {
      if (snapshot.val() !== null) {
        console.log("emails exists")
        // handle error
      } else {
        console.log("emails do not exists")
        // push record to Firebase
      }
    });
  }