#firebase #flask #firebase-storage #pyrebase
# #firebase #flask #firebase-хранилище #pyrebase
Вопрос:
По сути, моя проблема заключается в том, что я, по-видимому, не могу даже приблизиться к загрузке фотографий в мой проект Firebase. Я могу передавать информацию о пользователях в базу данных в реальном времени, а также успешно интегрировал аутентификацию Firebase, которую я использую с сеансами Flask для сохранения входа пользователей в систему. Похоже, что для сохранения файлов / фотографий вам нужно использовать хранилище Firebase, но я не могу понять, как это сделать.
Пользователи могут нажать и кнопку «загрузить файл» в моем маршруте «/ upload-image», и прямо сейчас я сохраняю изображение (после того, как пользователь загрузит его) в папку в том же каталоге, что и мой fiddl.py досье.
Весь следующий код находится в моем Fiddl.py
файле.
Вот мои инициализации Firebase:
Обратите внимание, storageRef
это то, что я пробовал, но такого, как ref()
в хранилище, нет, поэтому я получаю ошибки. Также у меня есть 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")
Вот конфигурации, которые я использовал для хранения загруженного пользователями изображения в локальной папке /FIDDL/Photo test
. Я сократил название пути для вашего удобства. Примечание: я надеюсь позже добавить эти конфигурации в их собственный файл для обеспечения безопасности, все еще не уверенный на 100%, как они должны работать. Наряду с этим у меня есть маршрут, по которому пользователь загружает фотографию со своего устройства.
#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")
Вот правила для Firebase /Development /Storage /Rules. Я использую аутентификацию Firebase, но все еще получаю сообщение об ошибке:
"code": 403,
"message": "Permission denied. Could not perform this operation"
}
Правила:
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;
}
}
}
Я знаю, что на самом деле здесь нет проблемы, которую нужно исправить, но любая точка в правильном направлении была бы супер! Спасибо!
Комментарии:
1. Как упоминалось здесь , просто сделайте что-то вроде
firebase.storage().child("images/example.jpg").put("example2.jpg")
— вы пробовали этот код?2. Я считаю, что это работает, поскольку правила для моего хранилища запрещают мне
put
использовать «error»: { «code»: 403, «message»: «Отказано в разрешении. Не удалось выполнить эту операцию » }3. Хм, вы уже настроили хранилище Firebase в своем проекте Firebase? Кроме того, возможно, проверьте, что ваши правила позволят вашему серверу добавлять файлы
4. Хорошо, ваше исправление сработало! Огромное спасибо @BlunderingPhilosopher! Теперь, чтобы отредактировать мои правила и выяснить, как правильно разрешать фотографии только аутентифицированным пользователям
put
. Я думаю, мне может понадобиться использовать Firebase Admin.5. Спасибо за всю вашу помощь @BlunderingPhilosopher! Я обязательно прочитаю это и внесу свои новые рабочие правки в свой исходный пост, поскольку было еще несколько исправлений, которые мне нужно было внести, чтобы все заработало! Лучшие.
Ответ №1:
Ответ TLDR, включая некоторые небольшие проверки файлов, является одной из причин, по которой у меня возникла проблема. Гораздо больше деталей выше, если необходимо.
Чтобы загрузить изображение / файл в хранилище Google Firebase:
firebase = pyrebase.initialize_app(json.load(open('firebase/firebaseConfig.json')))
storage = firebase.storage("gs://fiddl-dev.appspot.com")
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:
if request.method == "POST":
if request.files:
image = request.files["image"]
#Grab the file size
image.seek(0, os.SEEK_END) # Using seek here requires another later
file_size = image.tell()
#Check the image file size
if not allowed_image_filesize(file_size):
return redirect(request.url)
#Check for file name
if image.filename == "":
return redirect(request.url)
#Check if image has correct type
if not allow_image(image.filename):
return redirect(request.url)
else:
filename = secure_filename(image.filename) #create new secure file name
image.seek(0)
storage.child("images/" filename).put(image)
except:
...