private void deferredInitialization()

in firebase-database/src/main/java/com/google/firebase/database/core/Repo.java [109:231]


  private void deferredInitialization() {
    HostInfo hostInfo = new HostInfo(repoInfo.host, repoInfo.namespace, repoInfo.secure);
    connection = ctx.newPersistentConnection(hostInfo, this);

    this.ctx
        .getAuthTokenProvider()
        .addTokenChangeListener(
            ((DefaultRunLoop) ctx.getRunLoop()).getExecutorService(),
            new TokenProvider.TokenChangeListener() {
              @Override
              public void onTokenChange() {
                operationLogger.debug("Auth token changed, triggering auth token refresh");
                connection.refreshAuthToken();
              }

              @Override
              public void onTokenChange(String token) {
                operationLogger.debug("Auth token changed, triggering auth token refresh");
                connection.refreshAuthToken(token);
              }
            });

    this.ctx
        .getAppCheckTokenProvider()
        .addTokenChangeListener(
            ((DefaultRunLoop) ctx.getRunLoop()).getExecutorService(),
            new TokenProvider.TokenChangeListener() {
              @Override
              public void onTokenChange() {
                operationLogger.debug(
                    "App check token changed, triggering app check token refresh");
                connection.refreshAppCheckToken();
              }

              @Override
              public void onTokenChange(String token) {
                operationLogger.debug(
                    "App check token changed, triggering app check token refresh");
                connection.refreshAppCheckToken(token);
              }
            });

    // Open connection now so that by the time we are connected the deferred init has run
    // This relies on the fact that all callbacks run on repo's runloop.
    connection.initialize();

    PersistenceManager persistenceManager = ctx.getPersistenceManager(repoInfo.host);

    infoData = new SnapshotHolder();
    onDisconnect = new SparseSnapshotTree();

    transactionQueueTree = new Tree<List<TransactionData>>();

    infoSyncTree =
        new SyncTree(
            ctx,
            new NoopPersistenceManager(),
            new SyncTree.ListenProvider() {
              @Override
              public void startListening(
                  final QuerySpec query,
                  Tag tag,
                  final ListenHashProvider hash,
                  final SyncTree.CompletionListener onComplete) {
                scheduleNow(
                    new Runnable() {
                      @Override
                      public void run() {
                        // This is possibly a hack, but we have different semantics for .info
                        // endpoints. We don't raise null events on initial data...
                        final Node node = infoData.getNode(query.getPath());
                        if (!node.isEmpty()) {
                          List<? extends Event> infoEvents =
                              infoSyncTree.applyServerOverwrite(query.getPath(), node);
                          postEvents(infoEvents);
                          onComplete.onListenComplete(null);
                        }
                      }
                    });
              }

              @Override
              public void stopListening(QuerySpec query, Tag tag) {}
            });

    serverSyncTree =
        new SyncTree(
            ctx,
            persistenceManager,
            new SyncTree.ListenProvider() {
              @Override
              public void startListening(
                  QuerySpec query,
                  Tag tag,
                  ListenHashProvider hash,
                  final SyncTree.CompletionListener onListenComplete) {
                connection.listen(
                    query.getPath().asList(),
                    query.getParams().getWireProtocolParams(),
                    hash,
                    tag != null ? tag.getTagNumber() : null,
                    new RequestResultCallback() {
                      @Override
                      public void onRequestResult(String optErrorCode, String optErrorMessage) {
                        DatabaseError error = fromErrorCode(optErrorCode, optErrorMessage);
                        List<? extends Event> events = onListenComplete.onListenComplete(error);
                        postEvents(events);
                      }
                    });
              }

              @Override
              public void stopListening(QuerySpec query, Tag tag) {
                connection.unlisten(
                    query.getPath().asList(), query.getParams().getWireProtocolParams());
              }
            });

    restoreWrites(persistenceManager);

    updateInfo(Constants.DOT_INFO_AUTHENTICATED, false);
    updateInfo(Constants.DOT_INFO_CONNECTED, false);
  }