Adding new user to Cloud Firestore using Python Flask

Viewed 44

I am very new to using Flask and web development in general, and I have been trying to set up an account creation page on a new website with no luck. The branch url, /create_acct, displays as I want it to with email and password entry blocks and a submit button. When I try to submit a valid email/password combination, however, no new user is added to my Cloud Firestore database. And the website simply reloads the home page, /, rather than directing to the /my_account page. For invalid email/password combinations, the /create_account page is not reloaded and a flash message doesn't appear.

My database has read and write accessibility set up correctly (I checked this by manually adding users to the database in the Python terminal), so I don't think that's the issue. Here's my Python code:

# import flask package, firebase_admin for database ops
from flask import Flask, session, render_template, request, redirect, url_for, flash
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore

### create app object using flask
app = Flask(__name__)

config = {
    "apiKey": "[]",
    "authDomain": "[]",
    "projectId": "[]",
    "storageBucket": "[]",
    "messagingSenderId": "[]",
    "appId": "[]",
    "measurementId": "[]",
    "databaseURL": "[website url]"
  }

### secret key (auto-generated)
app.secret_key = '[secretkey]'

### initialize firestore database
cred = credentials.Certificate("[pathtoprivatekey].json")
firebase_admin.initialize_app(cred)
db = firestore.client()

### create new users
@app.route('/create_acct', methods=['POST', 'GET'])
def create_user(email: str, password: str):
  if request.method == 'POST':
    email = request.form['email']
    password = request.form['password']
    data_to_push = {'email': email, 'password': password}
    
    if password=='' or email=='':
      flash('Please enter a password at least 7 characters long, containing at least two numbers, four letters, and one special character.')
      return redirect(url_for('create_acct'))
    else:
      if len(password)<7:
        flash('Please enter a password at least 7 characters long, containing at least two numbers, four letters, and one special character.')
        return redirect(url_for('create_acct'))
      else:
        # count numeric characters in password
        dig_count = 0
        alpha_count = 0
        
        for i in range(0,len(password)+1):
          if password[i].isdigit()==True:
            dig_count = dig_count+1
          if password[i].isalpha()==True:
            alpha_count = alpha_count+1
        if dig_count<2:
          flash('Please enter a password at least 7 characters long, containing at least two numbers, four letters, and one special character.')
          return redirect(url_for('create_acct'))
        elif alpha_count<4:
          flash('Please enter a password at least 7 characters long, containing at least two numbers, four letters, and one special character.')
          return redirect(url_for('create_acct'))
        elif password.isalnum() == True:
          flash('Please enter a password at least 7 characters long, containing at least two numbers, four letters, and one special character.')
          return redirect(url_for('create_acct'))
        else:
          # db.child('users').push(data_to_push)
          db.collection('users').document().set(data_to_push)
          return redirect(url_for('my_account'))

  return render_template('index.html')

...and my html template for /create_account:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="static/style.css" />
    <title>Create an account</title>
</head>
<body>
    <div class="toplinks">
        <a href="/" class="button">Home</a>
        <a href="/my_account" class="button">My Account</a>
        <a href="/about" class="button">How It Works</a>
        <a href="/news" class="button">In the News</a>
    </div>

    {% for message in get_flashed_messages() %}
    <h2>{{ message }}</h2>
    {% endfor %}

    <div class="container">
        <form action="/" method="POST">
        <h2>Log in or create an account</h2>
            <div class="form-group">
                <h3>Email</h3>
                <input type="text"
                    name="email"
                    id="email"
                    placeholder="Email@domain"
                >
            </div>
            <div class="form-group">
                <h3>Password</h3>
                <input type="text"
                    name="password"
                    id="password"
                    placeholder="************"
                >
            </div>
            <input type="submit">
        </form>
    </div>
</body>
</html>

0 Answers
Related