skip to Main Content

Firebase is throwing continuous errors when the app goes offline. I don’t know where the errors are coming from so I can catch them.

The errors stop when the user comes back online.
I am using listeners to listen to Firebase firestore collections and documents.

This is the error:

V/NativeCrypto(26596): Read error: ssl=0xb4000074b15e4318: I/O error during system call, Software caused connection abort
V/NativeCrypto(26596): Write error: ssl=0xb4000074b15e4318: I/O error during system call, Broken pipe
W/ManagedChannelImpl(26596): [{0}] Failed to resolve name. status={1}
D/TrafficStats(26596): tagSocket(3) with statsTag=0xffffffff, statsUid=-1
W/ManagedChannelImpl(26596): [{0}] Failed to resolve name. status={1}
W/Firestore(26596): (24.9.1) [WatchStream]: (9f3395b) Stream closed with status: Status{code=UNAVAILABLE, description=End of stream or IOException, cause=null}.
V/NativeCrypto(26596): SSL shutdown failed: ssl=0xb4000074b15e4318: I/O error during system call, Success
W/Firestore(26596): (24.9.1) [WatchStream]: (9f3395b) Stream closed with status: Status{code=UNAVAILABLE, description=Unable to resolve host firestore.googleapis.com, cause=java.lang.RuntimeException: java.net.UnknownHostException: Unable to resolve host "firestore.googleapis.com": No address associated with hostname
W/Firestore(26596):     at io.grpc.internal.DnsNameResolver.resolveAddresses(DnsNameResolver.java:223)
W/Firestore(26596):     at io.grpc.internal.DnsNameResolver.doResolve(DnsNameResolver.java:282)
W/Firestore(26596):     at io.grpc.internal.DnsNameResolver$Resolve.run(DnsNameResolver.java:318)
W/Firestore(26596):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
W/Firestore(26596):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
W/Firestore(26596):     at java.lang.Thread.run(Thread.java:1012)
W/Firestore(26596): Caused by: java.net.UnknownHostException: Unable to resolve host "firestore.googleapis.com": No address associated with hostname
W/Firestore(26596):     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:124)
W/Firestore(26596):     at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
W/Firestore(26596):     at java.net.InetAddress.getAllByName(InetAddress.java:1152)
W/Firestore(26596):     at io.grpc.internal.DnsNameResolver$JdkAddressResolver.resolveAddress(DnsNameResolver.java:631)
W/Firestore(26596):     at io.grpc.internal.DnsNameResolver.resolveAddresses(DnsNameResolver.java:219)
W/Firestore(26596):     ... 5 more
W/Firestore(26596): }.

After that, the error keeps repeating like:

W/ManagedChannelImpl(26596): [{0}] Failed to resolve name. status={1}
W/Firestore(26596): (24.9.1) [WatchStream]: (9f3395b) Stream closed with status: Status{code=UNAVAILABLE, description=Unable to resolve host firestore.googleapis.com, cause=java.lang.RuntimeException: java.net.UnknownHostException: Unable to resolve host "firestore.googleapis.com": No address associated with hostname
W/Firestore(26596):     at io.grpc.internal.DnsNameResolver.resolveAddresses(DnsNameResolver.java:223)
W/Firestore(26596):     at io.grpc.internal.DnsNameResolver.doResolve(DnsNameResolver.java:282)
W/Firestore(26596):     at io.grpc.internal.DnsNameResolver$Resolve.run(DnsNameResolver.java:318)
W/Firestore(26596):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
W/Firestore(26596):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
W/Firestore(26596):     at java.lang.Thread.run(Thread.java:1012)
W/Firestore(26596): Caused by: java.net.UnknownHostException: Unable to resolve host "firestore.googleapis.com": No address associated with hostname
W/Firestore(26596):     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:124)
W/Firestore(26596):     at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
W/Firestore(26596):     at java.net.InetAddress.getAllByName(InetAddress.java:1152)
W/Firestore(26596):     at io.grpc.internal.DnsNameResolver$JdkAddressResolver.resolveAddress(DnsNameResolver.java:631)
W/Firestore(26596):     at io.grpc.internal.DnsNameResolver.resolveAddresses(DnsNameResolver.java:219)
W/Firestore(26596):     ... 5 more
W/Firestore(26596): }.

Please help.

2

Answers


  1. Chosen as BEST ANSWER

    To stop the continuous errors, you have to cancel any listeners you have active on a Firestore collection or document.

    I created a Cubit that keeps track of whether the user is connected to the internet with the connectivity_plus plugin. Then I listened to the cubit in the cubit that contains the listener and based on the online state, I cancel or reconnect the listener.

    Now, the error is only thrown the first time before the listener is cancelled.

    Here is the code for the connectivity cubit:

    import 'dart:async';
    
    import 'package:connectivity_plus/connectivity_plus.dart';
    import 'package:flutter_bloc/flutter_bloc.dart';
    
    class OnlineStatusManager extends Cubit<ConnectivityResult> {
      OnlineStatusManager() : super(ConnectivityResult.none) {
        _statusSubscription = Connectivity()
            .onConnectivityChanged
            .listen((ConnectivityResult result) {
          emit(result);
        });
      }
    
      bool get isOnline => state != ConnectivityResult.none;
    
      late final StreamSubscription _statusSubscription;
    
      @override
      Future<void> close() async {
        await _statusSubscription.cancel();
        return super.close();
      }
    }
    

    Here is how I used it:

    class UserManager extends Cubit<UserData?> {
    
      StreamSubscription? _sourceSubscription;
      late final StreamSubscription<ConnectivityResult> _onlineStatusSubscription;
    
      UserManager() : super(null) {
        // The listener does not trigger on connection. Only on changes.
        // So it is necessary to set the initial value
        if (FirebaseAuth.instance.currentUser != null) {
          if (locator<OnlineStatusManager>().isOnline) {
            _sourceSubscription = _source.changes().listen(_apiChangesListener);
          }
        }
    
        _onlineStatusSubscription =
            locator<OnlineStatusManager>().stream.listen(_onlineStatusListener);
      }
    
      void _resetRemoteListener() {
        if (FirebaseAuth.instance.currentUser != null) {
          _sourceSubscription = _source.changes().listen(_apiChangesListener);
        }
      }
    
      void _onlineStatusListener(ConnectivityResult result) {
        if (result == ConnectivityResult.none) {
          _sourceSubscription?.cancel();
        } else {
          _resetRemoteListener();
          print('=========== Reconnected listeners +============== ');
        }
      }
    
      void _apiChangesListener(DocumentSnapshot newUser) {
        if (newUser.exists) {
          cacheUser(UserData.fromMap((newUser.data()! as Map).cast()));
        } else {
          _local.deleteUser();
          emit(null);
        }
      }
    
      @override
      Future<void> close() async {
        await _sourceSubscription?.cancel();
        await _onlineStatusSubscription.cancel();
        super.close();
      }
    
    }
    

  2. These are not errors you can catch, and the Firestore SDK does not consider it to be an "error" to be offline. Being offline is just a condition that it handles for you.

    The Firestore SDK on all platforms automatically falls back to the local persistence layer while offline, and tries to reconnect while the app is running so that you can transition seamlessly back to the online service.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search