Цей посібник описує покроковий процес створення та підключення нового репозиторію FirebaseStudentRepository поруч із існуючим StudentRepository (EF Core) із використанням паттерну Repository та Dependency Injection.
Для роботи з Firebase Realtime Database через Web API встановіть пакет FirebaseDatabase.net.
Відкрийте Terminal у Visual Studio / JetBrains Rider або командну стрічку в папці проєкту та виконайте:
dotnet add package FirebaseDatabase.netДодайте секцію "Firebase" у файл appsettings.json. Рядок підключення SQL Server залишається без змін.
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=Students;Integrated Security=SSPI;TrustServerCertificate=true"
},
"Firebase": {
"ApiKey": "",
"AuthDomain": "",
"DatabaseUrl": "",
"ProjectId": "",
"StorageBucket": "",
"MessagingSenderId": "",
"AppId": ""
}
}
⚠️ Порада щодо безпеки: не публікуйте реальні ключі Firebase у відкритих репозиторіях (наприклад, GitHub). Для продакшн-середовища використовуйте User Secrets або змінні середовища.
Переконайтеся, що модель не містить специфічних анотацій для Cloud Firestore. Залишаємо лише анотації [Display] для представлень MVC.
Файл: Models/Student.cs (або Student.cs у корені)
using System.ComponentModel.DataAnnotations;
namespace mvc
{
public class Student
{
public int Id { get; set; }
[Display(Name = "Ім'я")]
public string? Name { get; set; }
[Display(Name = "Прізвище")]
public string? Surname { get; set; }
[Display(Name = "Вік")]
public int Age { get; set; }
[Display(Name = "Середній бал")]
public double GPA { get; set; }
}
}Створіть новий файл Repository/FirebaseStudentRepository.cs поруч із StudentRepository.cs.
❗ Важливо: Не переписуйте та не видаляйте файл
StudentRepository.cs— обидва класи мають існувати паралельно.
Файл: Repository/FirebaseStudentRepository.cs
using Firebase.Database;
using Firebase.Database.Query;
using mvc;
namespace mvc.Repository
{
public class FirebaseStudentRepository : IRepository
{
private readonly FirebaseClient _firebaseClient;
private const string CollectionName = "students";
public FirebaseStudentRepository(IConfiguration config)
{
string databaseUrl = config["Firebase:DatabaseUrl"]
?? throw new InvalidOperationException("Firebase:DatabaseUrl не налаштовано в appsettings.json.");
_firebaseClient = new FirebaseClient(databaseUrl);
}
public async Task<List<Student>> GetStudentList()
{
try
{
// спроба зчитати дані як JSON-об'єкт/словник
var studentsDict = await _firebaseClient
.Child(CollectionName)
.OnceSingleAsync<Dictionary<string, Student>>();
if (studentsDict == null) return new List<Student>();
return studentsDict
.Where(pair => pair.Value != null)
.Select(pair =>
{
var student = pair.Value;
if (student.Id == 0 && int.TryParse(pair.Key, out int id))
{
student.Id = id;
}
return student;
}).ToList();
}
catch
{
// захист: якщо Firebase повернув JSON-масив виду [null, {...}]
var studentsList = await _firebaseClient
.Child(CollectionName)
.OnceSingleAsync<List<Student>>();
if (studentsList == null) return new List<Student>();
return studentsList
.Where(s => s != null)
.ToList();
}
}
public async Task<Student> GetStudent(int id)
{
var student = await _firebaseClient
.Child(CollectionName)
.Child(id.ToString())
.OnceSingleAsync<Student>();
if (student == null)
throw new InvalidOperationException($"Студента з айді {id} не знайдено.");
student.Id = id;
return student;
}
public async Task Create(Student item)
{
if (item.Id == 0)
{
var list = await GetStudentList();
item.Id = list.Any() ? list.Max(s => s.Id) + 1 : 1;
}
await _firebaseClient
.Child(CollectionName)
.Child(item.Id.ToString())
.PutAsync(item);
}
public void Update(Student item)
{
_firebaseClient
.Child(CollectionName)
.Child(item.Id.ToString())
.PutAsync(item)
.GetAwaiter()
.GetResult();
}
public async Task Delete(int id)
{
await _firebaseClient
.Child(CollectionName)
.Child(id.ToString())
.DeleteAsync();
}
public Task Save()
{
// зміни в Realtime Database зберігаються миттєво під час виклику PutAsync/DeleteAsync
return Task.CompletedTask;
}
}
}для генерик-версії інтерфейсу репозиторію реалізація може бути такою: https://claude.ai/share/71323584-1db5-4f22-a27f-066c5196baab
У файлі Program.cs зареєструйте новий репозиторій у контейнері Dependency Injection (builder.Services).
Щоб повернутися до SQL Server (EF Core), достатньо буде закоментувати рядок Firebase та розкоментувати рядок StudentRepository.
using Microsoft.EntityFrameworkCore;
using mvc.Repository;
namespace mvc
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// 1. Контекст EF Core (можна закоментувати, якщо SQL Server тимчасово не потрібен)
// string? connection = builder.Configuration.GetConnectionString("DefaultConnection");
// builder.Services.AddDbContext<StudentContext>(options => options.UseSqlServer(connection));
builder.Services.AddControllersWithViews();
// 2. Вибір джерела даних (DI):
// Варіант А: Робота через EF Core / SQL Server
// builder.Services.AddScoped<IRepository, StudentRepository>();
// Варіант Б: Робота через Firebase Realtime Database
builder.Services.AddScoped<IRepository, FirebaseStudentRepository>();
var app = builder.Build();
app.UseStaticFiles();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Student}/{action=Index}/{id?}");
app.Run();
}
}
}Для коректної роботи запитів без передачі приватного сервісного ключа перевірте правила доступу в базі даних:
- Перейдіть до Firebase Console.
- Відкрийте ваш проєкт → Build → Realtime Database.
- Перейдіть у вкладку Rules.
- Встановіть правила для тестування та натисніть Publish:
{
"rules": {
".read": true,
".write": true
}
}
⚠️ Увага: ці правила відкривають повний доступ на читання/запис для всіх — використовуйте їх лише для тестування, а перед продакшн-релізом налаштуйте автентифікацію та обмежені правила доступу.
| Крок | Дія |
|---|---|
| 1 | Встановлено пакет FirebaseDatabase.net |
| 2 | Додано конфігурацію Firebase в appsettings.json |
| 3 | Модель Student.cs без змін |
| 4 | Створено FirebaseStudentRepository.cs |
| 5 | Налаштовано перемикання репозиторіїв через DI у Program.cs |
| 6 | Налаштовано правила доступу в Firebase Console |
початкова версія проєкту: https://github.com/sunmeat/aspnetcore_repository