Firebase Storage е облачна услуга за съхранение на потребителски файлове, част от екосистемата Firebase на Google, предназначена за качване и изтегляне на изображения, видеа, аудио и други бинарни данни от мобилни и уеб приложения. За разлика от обикновения облачен диск, Storage се интегрира с Firebase Authentication и Security Rules, което позволява гъвкаво разграничаване на достъпа до всеки файл на ниво заявка. Според Google Firebase (2026), услугата обработва над 500 милиона файлови операции дневно, осигурявайки мащабируемо съхранение без необходимост от управление на сървърна инфраструктура.
Основни точки
Firebase Storage е облачно обектно хранилище, изградено на базата на Google Cloud Storage, което предоставя SDK за Android, iOS и уеб платформи. Всеки файл се съхранява като обект в Google Cloud bucket и се адресира чрез път, наподобяващ файлова система: gs://bucket-name/path/to/file.jpg. Размерът на един файл може да достигне 5 TB, което позволява съхранение на всякакви медийни данни без предварителна компресия.
Архитектурата на Firebase Storage използва референтен модел на връзки (gsutil references), а не класическа йерархия от папки, въпреки че SDK предоставя интерфейс с директории за удобство на разработчика. Физически всички обекти се съхраняват в плоското именно пространство на bucket-а, а виртуалните папки се създават с помощта на префикси на пътя. Това осигурява линейна производителност на търсене независимо от броя на файловете.
Основното предимство на Firebase Storage пред директното използване на Google Cloud Storage е вградената интеграция с Firebase Authentication и Security Rules. Разработчикът не трябва да настройва отделни IAM роли и служебни акаунти: правилата за достъп се пишат на декларативен език, подобен на Firebase Realtime Database Rules, и се прилагат автоматично при всяка заявка.
Bucket на Firebase Storage се създава автоматично при активиране на услугата в конзолата Firebase. Пътят до файл се изгражда по принципа /име_на_папка/име_на_файл и може да съдържа вложени нива. Препоръчва се организиране на пътища по схемата /users/{userId}/images/{imageId}.jpg за изолиране на данни между потребители. Такава структура опростява писането на правила за сигурност, тъй като пътят съдържа идентификация на собственика.
Важно е да разберете, че Firebase Storage не е релационна база данни или файлов сървър в класическия смисъл. Това е обектно хранилище, оптимизирано за операции за четене и запис на цели файлове. Актуализирането на част от файл не е възможно: при повторно качване със същия път старият обект се заменя с новия. За съхранение на малки структурирани данни използвайте Firebase Realtime Database или Cloud Firestore.
Ценообразуването на Firebase Storage зависи от обема на съхраняваните данни и броя на операциите. Безплатният тариф (Spark) включва 5 GB хранилище, 20 000 операции за запис и 50 000 операции за четене на ден. Платеният тариф (Blaze) се заплаща според действителното използване: $0,026 на GB съхранявани данни, $0,05 на 10 000 операции за запис и $0,004 на 10 000 операции за четене. Допълнително се таксува изходящият трафик.
За повечето мобилни приложения с няколко хиляди потребители безплатният лимит е достатъчен на етапа на прототипиране и тестване. При мащабиране до стотици хиляди потребители разходите за Storage рядко надвишават $50–$100 на месец при оптимизиран подход към качването и кеширане от страна на клиента.
Качване на файл във Firebase Storage се извършва чрез съответния метод на SDK, който приема път в хранилището и данни на файла (масив от байтове, URI, поток или Bitmap). SDK автоматично управлява връзката, сегментира файла на части при голям размер и предоставя обратни извиквания за проследяване на напредъка. Качването се извършва директно от клиентското устройство към Google Cloud, заобикаляйки вашия сървър, което намалява натоварването на собствената ви инфраструктура.
За Android Firebase Storage SDK използва класовете StorageReference и UploadTask. StorageReference се създава от кореновия път чрез Firebase.storage.reference и сочи към конкретен файл в bucket-а. UploadTask връща слушатели за напредък, пауза и завършване. При прекъсване на връзката UploadTask автоматично продължава качването от последния успешно предаден байт — това поведение се нарича възобновяемо качване (resumable upload).
Метаданните на файла (Content-Type, персонализирани полета) се предават чрез отделен обект SettableMetadata при стартиране на качването. Правилното задаване на Content-Type е критично за коректното показване на файлове в браузъра и работата на CDN кеширането. Firebase Storage поддържа всички стандартни MIME типове: image/jpeg, image/png, video/mp4, application/pdf и други.
Метаданните на файла съдържат системни полета (Content-Type, Cache-Control, Content-Disposition) и персонализирани двойки ключ-стойност (customMetadata). Системните полета управляват HTTP заглавките при изтегляне. Например Cache-Control: public, max-age=31536000 включва кеширане на отговора за една година, което значително намалява броя на повторните изтегляния на един и същ файл и спестява трафик.
Персонализираните метаданни са удобни за предаване на допълнителна информация за файла без създаване на отделна колекция във Firestore. Например в полето uploadedBy можете да запазите userId на потребителя, качил файла, което опростява реализацията на галерии с авторско съдържание. Персонализираните метаданни не са защитени отделно от Security Rules — достъпът до тях се регулира от същите правила като за самия файл.
При необходимост да качите множество файлове едновременно (например снимки от галерия) не се препоръчва стартиране на независими UploadTask паралелно без ограничения. На мобилни устройства паралелното качване на повече от 3–5 файла води до претоварване на мрежовия стек и тайм-аути. Оптималната стратегия е използване на конкурентен лимит 3 или последователно качване с показване на обща лента за напредък.
За сървърна обработка след качване (генериране на миниатюри, компресия, модериране на съдържание) използвайте тригера на Firebase Cloud Functions: functions.storage.object().onFinalize(). Тази функция се извиква автоматично след завършване на качването на всеки файл и може да запази обработено копие на друг път. Повече за това в раздела за типични сценарии.
Firebase Storage поддържа два начина за изтегляне: директно изтегляне чрез SDK с получаване на масив от байтове или локален файл, и получаване на директен download URL за достъп чрез HTTP. Директен URL може да се използва за показване на изображения в ImageView, в WebView или за предоставяне на връзка на потребителя. Download URL се генерира със защитен токен, който може да бъде оттеглен в конзолата Firebase.
Методът storageReference.downloadUrl връща URL във формат https://firebasestorage.googleapis.com/v0/b/{bucket}/o/{path}?alt=media&token={token}. Защитният токен автоматично се включва в URL при генериране, така че връзката може да бъде предадена на трети страни (например в месинджър) без риск от неоторизиран достъп. Ако обаче токенът е компрометиран, може да бъде оттеглен чрез конзолата Firebase в раздела Storage — след това всички връзки с този токен спират да работят.
За кеширане на изтеглени файлове от страна на клиента използвайте локално хранилище и механизъм ETag или MD5 хеш. Firebase Storage връща HTTP заглавка ETag при заявка за файл, която може да се сравни с локално запазена стойност, за да се избегне повторно изтегляне на непроменени файлове. Това е особено полезно за медийно съдържание: аватари, корици, прегледи — файлове, които рядко се актуализират, но често се заявяват.
Download URL с токен е основният начин за предоставяне на достъп до файлове за неудостоверени потребители (например за показване на изображение в новинарски поток). Токенът се генерира веднъж и не се променя до оттегляне, така че URL може да бъде запазен в базата данни (например до полето avatarUrl във Firestore). При смяна на аватар старият файл се изтрива и новият URL се генерира и запазва.
Важно е да запомните: наличието на download URL не отменя Security Rules. Ако правило забранява четене на файла, методът downloadUrl ще върне грешка Permission Denied. Това означава, че дори при знание на правилния път до файла, неудостовереният клиент не може да получи връзката. След получаване на URL, достъпът до файла се осъществява чрез HTTP, заобикаляйки Security Rules — следователно токенът е единствената защита на download връзката.
HTTP ETag е идентификатор на версията на файл, който се променя при всяка промяна на съдържанието. Firebase Storage автоматично връща ETag в отговора на GET заявка. Клиентското приложение може да запази ETag в локалния кеш и при повторна заявка да изпрати заглавка If-None-Match: {etag}. Ако файлът не се е променил, сървърът връща статус 304 Not Modified без прехвърляне на данни.
За реализация на интелигентно кеширане в мобилно приложение използвайте комбинация от локална файлова система и база данни (например Room за съхранение на двойки път-ETag). При изтегляне на файл проверете ETag от базата данни: ако съвпада със сървърната стойност, използвайте локалното копие. Такъв подход намалява трафика с 60–80% за статични медийни файлове и ускорява зареждането на екрани с галерии.
Security Rules е декларативен език за разграничаване на достъпа до файлове във Firebase Storage, изпълняван от страна на сървъра на Firebase. Всяко правило е обвързано с път в bucket-а и определя условията, при които е разрешена операция за четене (read) или запис (write). Правилата се проверяват преди всяка заявка и не могат да бъдат заобиколени от клиентски код. Това е единствената защитна линия на данните срещу неоторизиран достъп.
Основното правило — достъп само за удостоверени потребители: allow read, write: if request.auth != null. Такова правило гарантира, че само влезли в системата потребители могат да четат и записват файлове. За по-фино настройване се използва променливата request.auth.uid, която съдържа идентификатора на текущия потребител. Чрез сравняване на uid с част от пътя до файла може да се създаде изолирано хранилище за всеки потребител.
Важно: Security Rules не са механизъм за валидиране на съдържание. Ако трябва да проверите типа файл, неговия размер или наличие на злонамерен код, използвайте правилото request.resource, което съдържа метаданните на качвания файл. Налични са свойства request.resource.size (размер на файла), request.resource.contentType (MIME тип) и request.resource.md5Hash (контролна сума). Пълната проверка на съдържанието обаче се извършва от страна на сървъра чрез Cloud Functions.
| Сценарий | Правило на Security Rules |
|---|---|
| Само удостоверени | allow read, write: if request.auth != null |
| Само собственик | allow write: if request.auth.uid == userId |
| Публично четене | allow read: if true; allow write: if request.auth != null |
| Ограничение по размер | allow write: if request.resource.size < 5 * 1024 * 1024 |
| Ограничение по тип | allow write: if request.resource.contentType.startsWith('image/') |
Типична конфигурация за приложение с потребителски аватари и галерия изглежда по следния начин. Потребителят може да записва само в своята директория /users/{userId}/, но може да чете всеки файл в тази директория (галерията е публична). Размерът на файла е ограничен до 5 MB, а типът — само изображения. Такава комбинация от правила покрива 80% от сценариите за използване на Firebase Storage в социални и UGC приложения.
Съвет за сигурност: никога не използвайте правилото allow read, write: if true за целия bucket. Това отваря достъп за запис на всеки, който знае вашия projectId. През 2025 г. зачестиха атаките срещу незащитени Firebase bucket-ове, при които нападателите използваха отворен достъп за съхраняване на нелегално съдържание. Винаги започвайте с минимално необходимите права и ги разширявайте само при изрична необходимост.
Cloud Functions тригер functions.storage.object().onFinalize() позволява проверка на съдържанието след качване. Ако файлът не премине валидация (например съдържа вирус или нарушава правилата на платформата), функцията може да го изтрие и да уведоми потребителя. Това е единственият начин за проверка на действителното съдържание, тъй като Security Rules виждат само метаданни (размер и MIME тип), а не бинарни данни.
Пример за валидация: функция на Node.js изтегля качения файл във временна директория, прогонва го през антивирусен детектор (например ClamAV) и ако бъде открита заплаха — изтрива файла и записва събитие във Firebase Crashlytics. Времето за изпълнение на функцията е ограничено до 540 секунди, което е достатъчно за проверка на файлове до 50 MB.
Нека разгледаме практически примери за интеграция на Firebase Storage в Android приложение на Kotlin. Кодът използва стандартните класове на Firebase SDK и демонстрира качване на изображение от галерията на устройството, изтегляне на файл с проследяване на напредъка и получаване на download URL. Всички примери са изпълнени с обработка на грешки и暂停ване на задачи при загуба на връзка.
Преди да използвате кода, уверете се, че във файла build.gradle е добавена зависимостта implementation(platform("com.google.firebase:firebase-bom:33.0.0")) и implementation("com.google.firebase:firebase-storage"). Firebase BOM автоматично избира съвместими версии на всички SDK, което изключва конфликти на версии.
Първият пример — качване на файл, избран от потребителя чрез Intent ACTION_GET_CONTENT. URI на получения файл се предава на Firebase Storage SDK, който самостоятелно чете данните от този URI. Методът putFile приема URI и връща UploadTask — обект, чрез който може да се проследява напредъкът, да се поставя на пауза и да се възобновява качването.
val storageRef = Firebase.storage.reference
val imageRef = storageRef.child(
"users/${auth.uid}/profile.jpg"
)
val metadata = SettableMetadata().apply {
contentType = "image/jpeg"
customMetadata = mapOf(
"uploadedBy" to auth.uid!!
)
}
imageRef.putFile(imageUri, metadata)
.addOnSuccessListener {
Log.d("Storage", "Файлът е качен")
}
.addOnFailureListener { e ->
Log.e("Storage", "Грешка: ${e.message}")
}
В горния пример променливата storageRef е коренова референция към bucket-а на проекта. Методът child приема низ от пътя и връща StorageReference, сочеща към конкретен файл. Ако файл на указания път вече съществува, той ще бъде презаписан. Метаданните contentType и customMetadata се предават чрез обект SettableMetadata, който се прикрепя към заявката putFile.
Вторият пример демонстрира изтегляне на файл с получаване на масив от байтове за показване в ImageView. Методът getBytes(
val islandRef = storageRef.child("images/island.jpg")
val ONE_MEGABYTE: Long = 1024 * 1024
islandRef.getBytes(ONE_MEGABYTE)
.addOnSuccessListener { bytes ->
imageView.setImageBitmap(
BitmapFactory.decodeByteArray(
bytes, 0, bytes.size
)
)
}
.addOnFailureListener { e ->
Log.e("Storage", "Неуспешно качване: ${e.message}")
}
За получаване на download URL (например за запазване на връзка във Firestore) се използва методът downloadUrl:
islandRef.downloadUrl.addOnSuccessListener { uri ->
Log.d("Storage", "Download URL: $uri")
// Запазване на uri.toString() във Firestore
}
Съвет: downloadUrl се генерира веднъж и е стабилен, докато не бъде оттеглен. Запазвайте го в базата данни при първото качване, не го изисквайте всеки път при показване на файла. Това намалява броя на заявките към Firebase Storage и ускорява работата на UI.
Firebase Storage се използва в мобилни приложения за съхранение на всички потребителски и системни файлове. Най-честите сценарии са аватари и профилни снимки, изображения в поток от съдържание, видео и аудио файлове, документи (PDF, DOCX) за обмен между потребители, както и архивиране на малко количество данни. Във всички тези случаи Storage действа като специализирано файлово хранилище в комбинация с Firestore за съхранение на метаданни и връзки.
Социални приложения — най-честият случай. Всеки потребител качва аватар, снимки на публикации и медийни файлове. Структурата на пътищата /users/{uid}/posts/{postId}/image.jpg позволява изолиране на данни и опростява Security Rules. При изтриване на потребител Cloud Function може да обходи всички директории на потребителя и да почисти хранилището. Според блога на Firebase (2025) този модел се използва в 70% от продукционните проекти на Firebase.
E-commerce приложения използват Firebase Storage за съхранение на снимки на продукти, каталози и PDF файлове с инструкции. В този случай достъпът до файловете обикновено е публичен (четене без удостоверяване), а записът — само за администратори чрез Cloud Functions с проверка на правата. Download URL на продуктите се съхранява във Firestore до останалите данни за продукта, което позволява показване на изображения без допълнителни заявки към Storage.
Месинджъри и чатове съхраняват във Firebase Storage изображения и гласови съобщения, изпратени в диалози. Пътят се изгражда като /chats/{chatId}/messages/{messageId}.jpg. Достъп за четене — само на участниците в чата, което се проверява чрез Security Rules с използване на данни от Firestore. Това е един от малкото сценарии, при които правилото чете данни от друга Firebase услуга: allow read: if firestore.exists(/databases/(default)/documents/chats/{chatId}/members/{request.auth.uid}).
Често задавани въпроси
Firebase Storage е надстройка над Google Cloud Storage с интеграция на Firebase Authentication и Security Rules. Разработчикът не трябва да настройва IAM роли и служебни акаунти. Google Cloud Storage предоставя по-широки възможности (Pub/Sub известия, Object Lifecycle Management), но изисква ръчно управление на достъпа чрез GCP IAM.
Ограничението на размера се задава в Security Rules чрез request.resource.size. Пример: allow write: if request.resource.size <= 5 * 1024 * 1024 ограничава файловете до 5 MB. Допълнително можете да проверявате от страна на клиента преди изпращане, за да не губите трафик на потребителя при явно недопустим файл.
Да, за изтриване се използва методът delete() на обекта StorageReference: storageRef.child("path").delete(). Операцията за изтриване е необратима и незабавно премахва файла от bucket-а. Файл може да бъде изтрит само ако Security Rules разрешават write за този път. След изтриване download URL спира да работи.
В Security Rules разрешете read за всички (или удостоверени) и забранете write: allow read: if request.auth != null; allow write: if false. Запис в този режим е възможен само чрез служебен акаунт на Firebase Admin SDK — например от Cloud Functions с административни права. Това е стандартен модел за каталози с продукти и публично съдържание.
UploadTask използва протокол за възобновяемо качване, базиран на HTTP PUT със сегментиране. При прекъсване качването продължава от последния потвърден байт, а не започва отначало. За включване на това поведение не е необходима допълнителна конфигурация — SDK го прави автоматично при размер на файла над 1 MB.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също