Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

package io.flutter.plugins.firebase.database

import android.util.Log
import androidx.annotation.NonNull
import com.google.android.gms.tasks.Task
import com.google.android.gms.tasks.TaskCompletionSource
Expand Down Expand Up @@ -485,7 +484,7 @@ class FirebaseDatabasePlugin :
}

private fun removeEventStreamHandlers() {
for ((eventChannel, streamHandler) in streamHandlers) {
for ((eventChannel, streamHandler) in streamHandlers.toMap()) {
streamHandler?.onCancel(null)
eventChannel.setStreamHandler(null)
}
Expand Down Expand Up @@ -847,20 +846,21 @@ class FirebaseDatabasePlugin :

override fun queryObserve(app: DatabasePigeonFirebaseApp, request: QueryRequest, callback: (KotlinResult<String>) -> Unit) {
try {
Log.d("FirebaseDatabase", "🔍 Kotlin: Setting up query observe for path=${request.path}")
val database = getDatabaseFromPigeonApp(app)
val reference = database.getReference(request.path)
val query = queryFromModifiers(reference, request.modifiers)

// Generate a unique channel name
val channelName = "firebase_database_query_${System.currentTimeMillis()}_${request.path.hashCode()}"
val channelName =
synchronized(this) { "firebase_database_query_${listenerCount++}" }

// Set up the event channel
val eventChannel = EventChannel(messenger, channelName)
val streamHandler = EventStreamHandler(query, object : OnDispose {
override fun run() {
// Clean up when the stream is disposed
eventChannel.setStreamHandler(null)
eventChannel.setStreamHandler(null)
streamHandlers.remove(eventChannel)
}
})
eventChannel.setStreamHandler(streamHandler)
Expand Down
37 changes: 37 additions & 0 deletions tests/integration_test/firebase_database/query_e2e.dart
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,43 @@ void setupQueryTests() {
);
});

test(
'cancels overlapping query streams without missing plugin',
() async {
const subscriptionCount = 128;
final queryRef = ref.child('overlapping-query-streams');
await queryRef.set({'value': 1});

final errors = <Object>[];
final subscriptions = <StreamSubscription<DatabaseEvent>>[];
final firstEventsReceived = Completer<void>();
var firstEventCount = 0;

for (var i = 0; i < subscriptionCount; i++) {
subscriptions.add(
queryRef.onValue.listen(
(_) {
firstEventCount++;
if (firstEventCount >= subscriptionCount &&
!firstEventsReceived.isCompleted) {
firstEventsReceived.complete();
}
},
onError: errors.add,
),
);
}

await firstEventsReceived.future.timeout(const Duration(seconds: 10));
await Future.wait(
subscriptions.map((subscription) => subscription.cancel()),
);

expect(errors, isEmpty);
},
skip: defaultTargetPlatform != TargetPlatform.android,
);

test(
'throw a `permission-denied` exception when accessing restricted data',
() async {
Expand Down
Loading