Skip to content
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
Cannot retrieve contributors at this time

Frequently Asked Questions

Q: Where can I find server logs when running in Docker?

A: The log is in the container at /var/log/tinode.log. Attach to a running container with command

docker exec -it name-of-the-running-container /bin/bash

Then, for instance, see the log with tail -50 /var/log/tinode.log

If the container has stopped already, you can copy the log out of the container (saving it to ./tinode.log):

docker cp name-of-the-container:/var/log/tinode.log ./tinode.log

Alternatively, you can instruct the docker container to save the logs to a directory on the host by mapping a host directory to /var/log/ in the container. Add -v /where/to/save/logs:/var/log to the docker run command.

Q: What are the options for enabling push notifications?

A: You can use Tinode Push Gateway (TNPG) or you can use Google FCM:

  • Tinode Push Gateway requires minimum configuration changes by sending pushes on behalf of Tinode.
  • Google FCM does not rely on Tinode infrastructure for pushes but requires you to build your own mobile apps (iOS and Android).

Q: How to setup push notifications with Tinode Push Gateway?

A: Enabling TNPG push notifications requires two steps:

  • register at and obtain a TNPG token.
  • configure server with the token. See detailed instructions here.

Q: How to setup push notifications with Google FCM?

A: This option requires you to build and release your own mobile apps. If you do not want to do it, the the TNPG option above.

Enabling FCM push notifications requires the following steps:

  • enable push sending from the server
  • enable receiving pushes in the clients

Server and TinodeWeb

  1. Create a project at if you have not done so already.
  2. Follow instructions at to download the credentials file.
  3. Update the server config tinode.conf, section "push" -> "name": "fcm". Do ONE of the following:
  • Either enter the path to the downloaded credentials file into "credentials_file".
  • OR copy the file contents to "credentials".

    Remove the other entry. I.e. if you have updated "credentials_file", remove "credentials" and vice versa.
  1. Update TinodeWeb config firebase-init.js: update apiKey, messagingSenderId, projectId, appId, messagingVapidKey. See more info at

iOS and Android

  1. If you are using an Android client, add google-services.json to Tindroid by following instructions at and recompile the client. You may also optionally submit it to Google Play Store. See more info at
  2. If you are using an iOS client, add GoogleService-Info.plist to Tinodios by following instructions at and recompile the client. You may optionally submit the app to Apple AppStore. See more info at

Q: How to add new users?

A: There are three ways to create accounts:

  • A user can create a new account using one of the applications (web, Android, iOS).
  • A new account can be created using tn-cli (acc command or useradd macro). The process can be scripted.
  • If the user already exists in an external database, the Tinode account can be automatically created on the first login using the rest authenticator.

Q: How to create a root user?

A: Starting with Tinode version 0.18 the root access can be granted to a user by running the following command:

./tinode-db -auth=ROOT -uid=usrAbcDef123 -scheme=basic

Where usrAbcDef123 is the ID of the user to update.

In version 0.17 and older the root access can be granted to a user only by executing a database query. First create or choose the user you want to promote to root then execute the query:

  • RethinkDB:
r.db('tinode').table('auth').get('basic:login-of-the-user-to-make-root').update({authLvl: 30})
  • MySQL:
USE 'tinode';
UPDATE auth SET authlvl=30 WHERE uname='basic:login-of-the-user-to-make-root';
  • MongoDB:
db.getCollection('auth').updateOne({_id: 'basic:login-of-the-user-to-make-root'}, {$set: {authlvl: 30}})

The test database has a stock user xena which has root access.

Q: Once the number of network connections reaches about 1000 per node, all kinds of problems start. Is this a bug?

A: It is likely not a bug. To ensure good server performance Linux limits the total number of open file descriptors (live network connections, open files) for each process at the kernel level. The default limit is usually 1024. There are other possible restrictions on the number of file descriptors. The problems you are experiencing are likely caused by exceeding one of the Linux-imposed limits. Please seek assistance of a system administrator.

Q: What is the difference between a group topic and a channel?

A: Channel is a special case of a group topic. Normal group topics allow limited number of subscribers (128 by default). Each subscriber can be managed individually: invited, removed, banned, promoted to administrator or owner, other access permissions can be personally adjusted. Group topics with enabled channel functionality additionally permit an unlimited number of readers. The readers have read-only access to the topic, they cannot be managed individually, cannot be invited or removed, they cannot post messages. Readers do not generate presence notifications when joining or un-joining the topic and do not receive presence notifications from normal group members. Readers receive channel messages with From field set to null, i.e. they do not know who personally posted any given message to the channel. Readers cannot delete channel messages.

Q: What is the proper way to format gRPC {pub content}?

A: The gPRC sends content field of a {pub} message as a byte array while the client applications expect it to be valid JSON. Consequently, you have to format the field to be valid JSON before passing it to gRPC. For example, to send a plain text Hello world message you have to send a quoted string "Hello world". In most cases the string you pass to the gRPC call would look like "\"Hello world\"" or '"Hello world"'.