Essentially my issue is I am unable to seemingly even come close to uploading photos to my Firebase Project. I am able to push user information to the Realtime Database and I successfully have integrated Firebase Authentication as well, which I use with Flask Sessions to keep users logged in. It appears that in order to save files/photos you need to use Firebase Storage, but I am unable to figure out how.
Users are able to click and "upload file" button in my '/upload-image' route and right now I have the image saved (after the user uploads it) to a folder in the same directory as my fiddl.py file.
All Following code is in my Fiddl.py file.
Here are my Firebase Initializations:
Note, storageRef is something I tried, but there is no such this as ref() in storage so I get errors. Also I have storage because I believe that references my Projects Storage.
#initialize database
firebase = pyrebase.initialize_app(json.load(open('firebase/firebaseConfig.json')))
auth = firebase.auth()
db = firebase.database()
#storageRef = firebase.storage.ref() #Points to the root reference
app.secret_key = os.urandom(24) #secret key:track if user is logged in
storage = firebase.storage("gs://fiddl-dev.appspot.com")
Here is the configs I used to store the users uploaded image in the local folder /FIDDL/Photo test. I shortened the name of the path for your convenience. Side Note I hope to add these config's to their own file for security later, still not 100% sure how these are supposed to work. Along with this is the route I have that has the user upload a photo from their device.
#temp image upload location
#TODO: put these in a private config file
app.config["IMAGE_UPLOAD"] = "/FIDDL//photosTest"
app.config["ALLOWED_IMAGE_EXTENSIONS"] = ["PNG", "JPG", "JPEG"]
app.config["MAX_IMAGE_FILESIZE"] = 1.5 * 1024 * 1024 #1,572,864 Bytes or 1572.864 KB
# Upload Image
@app.route('/upload-image', methods=["GET", "POST"])
def upload_image():
try:
print(session['usr']) #this is equal to logged in users id token-> user['idToken']
app.logger.info("A user is already logged in")
#TODO: add a logout button, make sure to delete session for use on logout
# Alert Messages
noFileName = 'Image must have a file name.'
badFileSize = 'Image file size is too large.'
badFileName = 'That image extension or file name is not allowed'
dataAdded = 'User photos added to realtime database'
if request.method == "POST":
if request.files:
image = request.files["image"] #works the same as user input emal in register, get the image file
print(image)
#Grab the file size
image.seek(0, os.SEEK_END)
file_size = image.tell()
app.logger.info("Image File Size: ")
app.logger.info(file_size)
#Check the image file size
if not allowed_image_filesize(file_size):
#TODO: alert user on screen of the issue
app.logger.info(badFileSize)
return redirect(request.url)
#Check for file name
if image.filename == "":
app.logger.info(noFileName)
return redirect(request.url)
#Check if image has correct type
if not allow_image(image.filename):
app.logger.info(badFileName)
return redirect(request.url)
else:
filename = secure_filename(image.filename) #create new secure file name
app.logger.info(filename)
print(auth.current_user)
#Add data to realtime database
#TODO: figure out how to store photos in firebase
#Update progress
app.logger.info(dataAdded)
#image.save(os.path.join(app.config["IMAGE_UPLOAD"], filename)) #save images to /photosTest for testing
#print("image saved")
return redirect(request.url)
except KeyError:
app.logger.info("No user logged in, redirect to login")
return redirect(url_for('login'))
return render_template("upload_image.html")
Here are the rules for Firebase/Develop/Storage/Rules. I am using Firebase Authentication but am still getting the error:
"code": 403,
"message": "Permission denied. Could not perform this operation"
}
Rules:
rules_version = '2';
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/fiddl-dev.appspot.com/o {
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow write: if request.auth != null;
allow read: if true;
}
}
}
I know there isn't really an issue to fix here, but any point in the right direction would be super! Thanks!
TLDR Answer, including some small file checks since those, is part of the reason I had the issue. Much more detail above if needed.
To upload an Image/file to Google Firebase Storage: