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>