Вопрос или проблема
Я пытаюсь подключить свое Android-приложение к базе данных Firestore. Я могу записывать данные в свою базу данных из приложения, но не могу их считывать.
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Cerebrospinal"
tools:targetApi="31">
<activity
android:name=".SudokuActivity"
android:exported="false" />
<activity
android:name=".Activity2048"
android:exported="false" />
<activity
android:name=".WordleActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
build.gradle на уровне приложения
plugins {
alias(libs.plugins.android.application)
id("com.google.gms.google-services")
}
android {
namespace = "com.example.cerebrospinal"
compileSdk = 34
defaultConfig {
applicationId = "com.example.cerebrospinal"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
dependencies {
implementation(platform("com.google.firebase:firebase-bom:33.5.1"))
implementation("com.google.firebase:firebase-analytics")
// Firestore
implementation("com.google.firebase:firebase-firestore:25.1.1")
// Другие зависимости Firebase/Play services
implementation("com.google.firebase:firebase-auth:21.0.1")
implementation("com.google.android.gms:play-services-auth:21.2.0")
// FirebaseUI (для аутентификации)
implementation("com.firebaseui:firebase-ui-auth:8.0.0")
implementation(libs.appcompat)
implementation(libs.material)
implementation(libs.activity)
implementation(libs.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
}
build.gradle на уровне проекта:
// Основной файл сборки, в котором вы можете добавить параметры конфигурации, общие для всех подпроектов/модулей.
plugins {
alias(libs.plugins.android.application) apply false
id("com.google.gms.google-services") version "4.4.2" apply false
}
Тестовый код, который я использую для доступа к своей базе данных:
oneButton = findViewById(R.id.button1);
oneButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (sudokuController.getPencilMode() && sudokuController.getSelectedRow() > 0
&& sudokuController.getSelectedColumn() > 0) {
sudokuController.setSelectedNumber(1);
sudokuController.setBoardTile();
sudokuBoard.invalidate();
}
FirebaseFirestore db = FirebaseFirestore.getInstance();
// Создание нового пользователя с именем и фамилией
Map<String, Object> user = new HashMap<>();
user.put("first", "Ада");
user.put("last", "Лавлейс");
user.put("born", 1815);
// Добавление нового документа с сгенерированным идентификатором
db.collection("users")
.add(user)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
@Override
public void onSuccess(DocumentReference documentReference) {
Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId());
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "Error adding document", e);
}
});
// Создание нового пользователя с именем, отчеством и фамилией
user = new HashMap<>();
user.put("first", "Алан");
user.put("middle", "Мэтиссон");
user.put("last", "Тьюринг");
user.put("born", 1912);
// Добавление нового документа с сгенерированным идентификатором
db.collection("users")
.add(user)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
@Override
public void onSuccess(DocumentReference documentReference) {
Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId());
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "Error adding document", e);
}
});
db.collection("users")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
}
} else {
Log.w(TAG, "Error getting documents.", task.getException());
}
}
});
}
});
Вывод Logcat после нажатия кнопки “oneButton”:
2024-11-14 19:37:17.284 9790-9849 ProfileInstaller com.example.cerebrospinal D Установка профиля для com.example.cerebrospinal
2024-11-14 19:37:19.383 9790-9809 EGL_emulation com.example.cerebrospinal D app_time_stats: avg=304.30ms min=13.14ms max=3634.54ms count=13
2024-11-14 19:37:19.620 9790-9790 ContentValues com.example.cerebrospinal D ArTLEmYycQ7AkM3Autjg => {middle=Mathison, last=Turing, born=1912, first=Alan}
2024-11-14 19:37:19.620 9790-9790 ContentValues com.example.cerebrospinal D JUIWkKMuC3wWTimIDdmP => {last=Lovelace, born=1815, first=Ada}
2024-11-14 19:37:19.620 9790-9790 ContentValues com.example.cerebrospinal D LQ1tECj91ivvL7ZhF7i8 => {last=Lovelace, born=1815, first=Ada}
2024-11-14 19:37:19.620 9790-9790 ContentValues com.example.cerebrospinal D xAmdrpHnykJarOA4ibt0 => {middle=Mathison, last=Turing, born=1912, first=Alan}
2024-11-14 19:37:19.724 9790-9790 ContentValues com.example.cerebrospinal D DocumentSnapshot added with ID: LQ1tECj91ivvL7ZhF7i8
2024-11-14 19:37:19.756 9790-9790 ContentValues com.example.cerebrospinal D DocumentSnapshot added with ID: xAmdrpHnykJarOA4ibt0
2024-11-14 19:37:25.332 9790-9840 GoogleApiManager com.example.cerebrospinal E Не удалось получить сервис от брокера. (Спросите у Gemini)
java.lang.SecurityException: Unknown calling package name 'com.google.android.gms'.
at android.os.Parcel.createExceptionOrNull(Parcel.java:3242)
at android.os.Parcel.createException(Parcel.java:3226)
at android.os.Parcel.readException(Parcel.java:3209)
at android.os.Parcel.readException(Parcel.java:3151)
at amxe.a(:com.google.android.gms@[email protected] (260800-693941914):36)
at amvl.z(:com.google.android.gms@[email protected] (260800-693941914):143)
at amcs.run(:com.google.android.gms@[email protected] (260800-693941914):54)
at android.os.Handler.handleCallback(Handler.java:959)
at android.os.Handler.dispatchMessage(Handler.java:100)
at bskq.mC(:com.google.android.gms@[email protected] (260800-693941914):1)
at bskq.dispatchMessage(:com.google.android.gms@[email protected] (260800-693941914):5)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.os.HandlerThread.run(HandlerThread.java:85)
2024-11-14 19:42:19.801 9790-9867 TrafficStats com.example.cerebrospinal D tagSocket(136) with statsTag=0xffffffff, statsUid=-1
2024-11-14 19:42:19.881 9790-9867 TrafficStats com.example.cerebrospinal D tagSocket(5) with statsTag=0xffffffff, statsUid=-1
Я следовал документации Android, чтобы использовать базу данных в своем приложении, и использую их пример кода для тестирования. Я ожидал, что смогу как считывать, так и записывать данные в/из своей базы данных, но не могу считывать из нее.
Спасибо за помощь!
Ответ или решение
Вопрос, связанный с невозможностью чтения данных из базы данных Firestore в приложении Android, может быть вызван несколькими возможными проблемами. Давайте разберем вашу ситуацию, учитывая предоставленный вами код, настройки манифеста и логи, чтобы определить возможные решения.
1. Проверка настроек правил доступа
Поскольку вы уже можете записывать данные в базу данных, это может указывать на правильность конфигурации Firebase в вашем проекте. Однако стоит проверить правила доступа Firestore. В соответствии с этими правилами, ваше приложение должно иметь права как на запись, так и на чтение. Вы можете упрощенно установить правила доступа следующим образом:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true; // Всем пользователям разрешен доступ
}
}
}
Обратите внимание: Данные правила разрешают всем доступ к вашей базе, что неприемлемо в продуктивной среде, но это поможет вам диагностировать проблемы.
2. Проверка подключения к Firestore
Вы можете проверить, установлено ли ваше приложение корректно и имеет ли оно доступ к Интернету. Если вы используете эмулятор, убедитесь, что он подключен к сети. Это можно сделать, открыв браузер в эмуляторе и посетив сайт.
Также убедитесь, что вы инициализируете Firestore правильно:
FirebaseFirestore db = FirebaseFirestore.getInstance();
3. Проверка кода чтения
Ваш код чтения данных выглядит корректно, однако стоит убедиться, что вы вызываете его после записи данных, и данные действительно были записаны. Проверьте, есть ли какие-либо исключения при выполнении кода чтения и добавьте дополнительную отладку:
db.collection("users")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d(TAG, document.getId() + " => " + document.getData());
}
} else {
Log.w(TAG, "Error getting documents.", task.getException());
}
}
});
Убедитесь также, что get()
вызывается только после успешного добавления пользователей и вне вложенных слушателей.
4. Подключение к Google Play Services
Ваши логи показывают ошибку, связанную с Google Play Services. Попробуйте следующее:
- Проверьте зависимости: Убедитесь, что все зависимости Google Play обновлены в
build.gradle
. - Обновите Google Play Services: Убедитесь, что на вашем устройстве или эмуляторе версии Play Services актуальны.
- Проверьте аутентификацию: Если вы используете аутентификацию в Firebase, настройте ее корректно, чтобы упростить процессы входа и доступа к данным.
5. Проверка логов
Логи, которые вы предоставили, указывают на проблему с идентификатором пакета. Это может происходить, если приложение не инициализировано должным образом или не может получить доступ к вашему проекту Firebase. Убедитесь, что вы правильно сконфигурировали google-services.json
и что он находится в вашем каталоге app/
.
Заключение
Если после выполнения всех предложенных шагов у вас все еще возникают проблемы с чтением данных из Firestore, убедитесь, что вы проверили все этапы интеграции Firebase в ваше Android-приложение. Перепроверьте ваши правила доступа, подключение к интернету и настройки Google Play Services. Это поможет вам выявить и устранить проблемы, позволяя вам успешно читать данные из Firestore.