我正在尝试将我的 Android 应用程序连接到我的 Firestore 数据库。我可以从我的应用程序写入数据库,但无法从中读取。
Android 清单:
<?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")
// Other Firebase/Play services deps
implementation("com.google.firebase:firebase-auth:21.0.1")
implementation("com.google.android.gms:play-services-auth:21.2.0")
// FirebaseUI (for authentication)
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:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
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();
// Create a new user with a first and last name
Map<String, Object> user = new HashMap<>();
user.put("first", "Ada");
user.put("last", "Lovelace");
user.put("born", 1815);
// Add a new document with a generated ID
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);
}
});
// Create a new user with a first, middle, and last name
user = new HashMap<>();
user.put("first", "Alan");
user.put("middle", "Mathison");
user.put("last", "Turing");
user.put("born", 1912);
// Add a new document with a generated ID
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());
}
}
});
}
});
按下“oneButton”后的Logcat输出:
2024-11-14 19:37:17.284 9790-9849 ProfileInstaller com.example.cerebrospinal D Installing profile for 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 Failed to get service from broker. (Ask 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 文档在我的应用程序中使用数据库,并使用他们的示例代码来测试它。我希望能够从/向我的数据库读取和写入,但无法从中读取。
我可以写入我的 Firebase Firestore 数据库,但无法从中读取。
这是正常行为,因为所有 Firebase Firestore 操作都是异步的。您想要做的是读取来自两个不同用户相加的数据,这不太可能,因为两个相加操作都需要时间。因此,当您尝试读取数据时,加法操作尚未完成,因此数据不可用,因此无法读取。解决方案总是相同的。应作为其他异步操作的结果执行的所有异步操作都需要位于 onSuccess/onComplete 方法内部或从那里调用。
因此,如果您需要读取两个用户的数据,那么您必须确保将数据添加到Firestore的两次操作都成功。您可以通过使用 自定义回调 或通过嵌套调用来实现此目的:
db.collection("users").add(user).addOnSuccessListener {
//Add it inside onSuccess
db.collection("users").add(user).addOnSuccessListener {
//Add it inside onSuccess
db.collection("users").get().addOnCompleteListener{
//Your logic.
}
}
}
因为您使用的是 Java,所以您可能会考虑实时使用可观察对象 LiveData。
如果您正在考虑在某个时间学习 Kotlin(我强烈推荐),那么您应该考虑使用 Kotlin Coroutines。这样,您将能够以更简单、更高效的方式等待操作完成。请检查以下一些资源: