我尝试使用Firebase中的事务编写一个函数来增加chatapp(android)中的未读消息计数。
我的数据库结构如下:
成员列表实际上可以包含超过2个用户进行群组聊天,我打算稍后进行扩展。
目前,可以将消息添加到messageList中,但在添加到messageList之后,我想为除发送者之外的所有其他用户增加unreadCount。我意识到我需要使用Transaction来使其成为原子,所以这是我的incrementUnreadCount代码。
private static void incrementUnreadCount(String chatRoomId) {
DatabaseReference mDatabaseMemberList = mDatabaseChatRooms.child(chatRoomId).child("memberList");
mDatabaseMemberList.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
Map<String, Map<String, Object>> tempMemberList = (Map<String, Map<String, Object>>) mutableData.getValue();
if (tempMemberList == null) {
return Transaction.abort();
}
for (String key : tempMemberList.keySet()) {
// if it is not a sender node
if (!key.equals(TutUserManager.getCurrentUid())) {
Map<String, Object> tempMap = tempMemberList.get(key);
long tempCount = (long) tempMap.get("unreadCount");
tempCount += 1;
tempMap.put("unreadCount", tempCount);
tempMemberList.put(key, tempMap);
}
}
mutableData.setValue(tempMemberList);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
}
});
}
以下代码仅在我发送第二条消息时有效。因此,unreadCount的值比预期的值小1。
我阅读了文档,并意识到对于null的情况,它应该是:
return Transaction.success(mutableData);
而不是:
return Transaction.abort();
as abort()将使服务器中止事务而不是再次尝试进行事务。
我尝试更改上面的代码以使用return ransaction.success(mutableData);
,但这会导致应用在调用函数时崩溃。
我错过了什么吗?
这是我从控制台获得的:
11/14 23:19:25: Launching app
No apk changes detected since last installation, skipping installation of C:\Users\Potcharaphol\AndroidStudioProjects\Tut\app\build\outputs\apk\app-debug.apk
$ adb shell am force-stop com.pchatanan.tut
$ adb shell am start -n "com.pchatanan.tut/com.pchatanan.tut.MainActivities.GetStartedActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
Waiting for application to come online: com.pchatanan.tut.test | com.pchatanan.tut
Connecting to com.pchatanan.tut
E/HAL: load: id=gralloc != hmi->id=gralloc
I/System.out: Sending WAIT chunk
I/art: Debugger is active
I/System.out: Debugger has connected
I/System.out: waiting for debugger to settle...
Connected to the target VM, address: 'localhost:8600', transport: 'socket'
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: debugger has settled (1339)
I/InstantRun: Instant Run Runtime started. Android package is com.pchatanan.tut, real application class is null.
[ 11-14 23:19:29.241 2931: 2931 E/ ]
process stopped due to unexpected signal 13
W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
[ 11-14 23:19:29.819 2931: 2931 E/ ]
process stopped due to unexpected signal 13
I/FA: App measurement is starting up, version: 9877
I/FA: To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
I/FA: To enable faster debug mode event logging run:
adb shell setprop firebase.analytics.debug-mode com.pchatanan.tut
I/HwCust: Constructor found for class android.app.HwCustAlarmManagerImpl
I/FirebaseInitProvider: FirebaseApp initialization successful
I/HwCust: Constructor found for class android.app.HwCustHwWallpaperManagerImpl
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
[ 11-14 23:19:30.422 2931: 2931 E/ ]
process stopped due to unexpected signal 13
I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
I/HwSecImmHelper: mSecurityInputMethodService is null
W/ActionBarDrawerToggle: DrawerToggle may not show up because NavigationIcon is not visible. You may need to call actionbar.setDisplayHomeAsUpEnabled(true);
I/DynamiteModule: Considering local module com.google.android.gms.firebase_database:4 and remote module com.google.android.gms.firebase_database:4
I/DynamiteModule: Selected remote version of com.google.android.gms.firebase_database, version >= 4
W/System: ClassLoader referenced unknown path: /data/user/0/com.google.android.gms/app_chimera/m/00000018/n/arm64-v8a
[ 11-14 23:19:31.068 2931: 2931 E/ ]
process stopped due to unexpected signal 13
E/HAL: load: id=gralloc != hmi->id=gralloc
I/OpenGLRenderer: Initialized EGL, version 1.4
I/System: core_booster, getBoosterConfig = false
I/System: core_booster, getBoosterConfig = false
[ 11-14 23:19:33.493 2931: 2931 E/ ]
process stopped due to unexpected signal 13
W/Settings: Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.
I/System: core_booster, getBoosterConfig = false
I/System: core_booster, getBoosterConfig = false
[ 11-14 23:19:35.396 2931: 2931 E/ ]
process stopped due to unexpected signal 13
I/HwSecImmHelper: mSecurityInputMethodService is null
I/HwSecImmHelper: mSecurityInputMethodService is null
I/HwSecImmHelper: mSecurityInputMethodService is null
W/art: Suspending all threads took: 14.466ms
I/FA: Tag Manager is not found and thus will not be used
I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
I/HwSecImmHelper: mSecurityInputMethodService is null
I/HwSecImmHelper: mSecurityInputMethodService is null
I/System: core_booster, getBoosterConfig = false
I/System: core_booster, getBoosterConfig = false
I/HwSecImmHelper: mSecurityInputMethodService is null
I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
E/RecyclerView: No adapter attached; skipping layout
I/HwSecImmHelper: mSecurityInputMethodService is null
I/HwSecImmHelper: mSecurityInputMethodService is null
E/RecyclerView: No adapter attached; skipping layout
I/HwSecImmHelper: mSecurityInputMethodService is null
I/HwSecImmHelper: mSecurityInputMethodService is null
I/HwSecImmHelper: mSecurityInputMethodService is null
I/HwSecImmHelper: mSecurityInputMethodService is null
W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
I/Process: Sending signal. PID: 20588 SIG: 9
Disconnected from the target VM, address: 'localhost:8600', transport: 'socket'
这是我从logcat获得的,似乎没有错误。
[ 11-14 23:21:49.129 2931: 2931 E/ ]
process stopped due to unexpected signal 13
11-14 23:21:49.321 21571-21571/com.pchatanan.tut I/System.out: waiting for debugger to settle...
11-14 23:21:49.522 21571-21571/com.pchatanan.tut I/System.out: waiting for debugger to settle...
11-14 23:21:49.723 21571-21571/com.pchatanan.tut I/System.out: waiting for debugger to settle...
[ 11-14 23:21:49.781 2931: 2931 E/ ]
process stopped due to unexpected signal 13
11-14 23:21:49.924 21571-21571/com.pchatanan.tut I/System.out: waiting for debugger to settle...
11-14 23:21:50.125 21571-21571/com.pchatanan.tut I/System.out: debugger has settled (1319)
11-14 23:21:50.149 21571-21571/com.pchatanan.tut I/InstantRun: Instant Run Runtime started. Android package is com.pchatanan.tut, real application class is null.
[ 11-14 23:21:50.364 2931: 2931 E/ ]
process stopped due to unexpected signal 13
11-14 23:21:50.842 21571-21633/com.pchatanan.tut W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
11-14 23:21:50.863 21571-21633/com.pchatanan.tut W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
11-14 23:21:50.973 21571-21571/com.pchatanan.tut I/FA: App measurement is starting up, version: 9877
11-14 23:21:50.973 21571-21571/com.pchatanan.tut I/FA: To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
11-14 23:21:50.980 21571-21571/com.pchatanan.tut I/FA: To enable faster debug mode event logging run:
adb shell setprop firebase.analytics.debug-mode com.pchatanan.tut
[ 11-14 23:21:50.999 2931: 2931 E/ ]
process stopped due to unexpected signal 13
11-14 23:21:51.035 21571-21571/com.pchatanan.tut I/HwCust: Constructor found for class android.app.HwCustAlarmManagerImpl
11-14 23:21:51.043 21571-21571/com.pchatanan.tut I/FirebaseInitProvider: FirebaseApp initialization successful
11-14 23:21:51.140 21571-21571/com.pchatanan.tut I/HwCust: Constructor found for class android.app.HwCustHwWallpaperManagerImpl
11-14 23:21:51.216 21571-21571/com.pchatanan.tut W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
11-14 23:21:51.601 21571-21571/com.pchatanan.tut I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
[ 11-14 23:21:51.609 2931: 2931 E/ ]
process stopped due to unexpected signal 13
11-14 23:21:51.875 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:21:51.925 21571-21571/com.pchatanan.tut W/ActionBarDrawerToggle: DrawerToggle may not show up because NavigationIcon is not visible. You may need to call actionbar.setDisplayHomeAsUpEnabled(true);
11-14 23:21:52.015 21571-21571/com.pchatanan.tut I/DynamiteModule: Considering local module com.google.android.gms.firebase_database:4 and remote module com.google.android.gms.firebase_database:4
11-14 23:21:52.015 21571-21571/com.pchatanan.tut I/DynamiteModule: Selected remote version of com.google.android.gms.firebase_database, version >= 4
11-14 23:21:52.030 21571-21571/com.pchatanan.tut W/System: ClassLoader referenced unknown path: /data/user/0/com.google.android.gms/app_chimera/m/00000018/n/arm64-v8a
11-14 23:21:52.192 21571-21651/com.pchatanan.tut E/HAL: load: id=gralloc != hmi->id=gralloc
11-14 23:21:52.193 21571-21651/com.pchatanan.tut I/OpenGLRenderer: Initialized EGL, version 1.4
11-14 23:21:52.194 21571-21666/com.pchatanan.tut I/System: core_booster, getBoosterConfig = false
[ 11-14 23:21:52.196 2931: 2931 E/ ]
process stopped due to unexpected signal 13
11-14 23:21:54.257 21571-21711/com.pchatanan.tut I/System: core_booster, getBoosterConfig = false
[ 11-14 23:21:54.586 2931: 2931 E/ ]
process stopped due to unexpected signal 13
[ 11-14 23:21:55.208 2931: 2931 E/ ]
process stopped due to unexpected signal 13
11-14 23:21:56.193 21571-21571/com.pchatanan.tut W/Settings: Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.
11-14 23:21:56.248 21571-21743/com.pchatanan.tut I/System: core_booster, getBoosterConfig = false
11-14 23:21:56.279 21571-21743/com.pchatanan.tut I/System: core_booster, getBoosterConfig = false
[ 11-14 23:21:56.442 2931: 2931 E/ ]
process stopped due to unexpected signal 13
[ 11-14 23:21:57.081 2931: 2931 E/ ]
process stopped due to unexpected signal 13
11-14 23:21:57.204 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:21:57.206 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:22:01.561 21571-21633/com.pchatanan.tut W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
[ 11-14 23:22:01.587 2931: 2931 E/ ]
process stopped due to unexpected signal 13
[ 11-14 23:22:02.195 2931: 2931 E/ ]
process stopped due to unexpected signal 13
[ 11-14 23:22:02.874 2931: 2931 E/ ]
process stopped due to unexpected signal 13
[ 11-14 23:22:03.487 2931: 2931 E/ ]
process stopped due to unexpected signal 13
11-14 23:22:07.605 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:22:07.720 21571-21641/com.pchatanan.tut I/FA: Tag Manager is not found and thus will not be used
11-14 23:22:07.775 21571-21571/com.pchatanan.tut I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
11-14 23:22:07.985 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:22:07.985 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:22:09.062 21571-21942/com.pchatanan.tut I/System: core_booster, getBoosterConfig = false
11-14 23:22:09.141 21571-21942/com.pchatanan.tut I/System: core_booster, getBoosterConfig = false
11-14 23:22:09.354 21571-21571/com.pchatanan.tut I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
11-14 23:22:09.454 21571-21571/com.pchatanan.tut E/RecyclerView: No adapter attached; skipping layout
11-14 23:22:09.471 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:22:09.472 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:22:09.476 21571-21571/com.pchatanan.tut E/RecyclerView: No adapter attached; skipping layout
11-14 23:22:10.246 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:22:10.308 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:22:10.309 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:22:10.313 21571-21571/com.pchatanan.tut I/HwSecImmHelper: mSecurityInputMethodService is null
11-14 23:22:13.747 21571-21571/com.pchatanan.tut I/Process: Sending signal. PID: 21571 SIG: 9
11-14 23:22:13.995 22048-22063/com.pchatanan.tut E/HAL: load: id=gralloc != hmi->id=gralloc
11-14 23:22:14.012 22048-22048/com.pchatanan.tut I/InstantRun: Instant Run Runtime started. Android package is com.pchatanan.tut, real application class is null.
11-14 23:22:14.575 22048-22083/com.pchatanan.tut W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
11-14 23:22:14.659 22086-22100/com.pchatanan.tut E/HAL: load: id=gralloc != hmi->id=gralloc
11-14 23:22:14.679 22086-22086/com.pchatanan.tut I/InstantRun: Instant Run Runtime started. Android package is com.pchatanan.tut, real application class is null.
11-14 23:22:15.323 22086-22133/com.pchatanan.tut W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
11-14 23:22:15.341 22086-22133/com.pchatanan.tut W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
11-14 23:22:15.462 22086-22086/com.pchatanan.tut I/FA: App measurement is starting up, version: 9877
11-14 23:22:15.462 22086-22086/com.pchatanan.tut I/FA: To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
11-14 23:22:15.471 22086-22086/com.pchatanan.tut I/FA: To enable faster debug mode event logging run:
adb shell setprop firebase.analytics.debug-mode com.pchatanan.tut
11-14 23:22:15.524 22086-22086/com.pchatanan.tut I/HwCust: Constructor found for class android.app.HwCustAlarmManagerImpl
11-14 23:22:15.532 22086-22086/com.pchatanan.tut I/FirebaseInitProvider: FirebaseApp initialization successful
11-14 23:22:25.611 22086-22133/com.pchatanan.tut W/DynamiteModule: Local module descriptor class for com.google.firebase.auth not found.
答案 0 :(得分:0)
我不是遍历Transaction线程中的每个节点,而是使用.addListenerForSingleValueEvent
并遍历每个节点。然后对于需要更新的那个,我运行事务代码。这种方法很好。
以下代码说明了这一点:
private static void incrementUnreadCount(String chatRoomId) {
final DatabaseReference mDatabaseMemberList = mDatabaseChatRooms.child(chatRoomId).child("memberList");
mDatabaseMemberList.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot child : dataSnapshot.getChildren()){
if(!child.getKey().equals(TutUserManager.getCurrentUid())){
mDatabaseMemberList.child(child.getKey()).runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
Map<String, Object> tempData = (Map<String, Object>) mutableData.getValue();
if(tempData == null){
return Transaction.success(mutableData);
}
long unreadCount = (long) tempData.get("unreadCount");
unreadCount += 1;
tempData.put("unreadCount", unreadCount);
mutableData.setValue(tempData);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {
}
});
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}