1) Have "tracker" servers set up around the world. The App needs to know at least one of the IPs, preferably all, in order to get a list of Peers it can connect to. This is still considered "decentralized" so long as none of the "trackers" is considered a "master" over the others.
2) Have UserA manually enter the IP of another UserB. Then, UserB tells UserA all of the Peers it knows about, which UserA will then connect to, and so on and so forth. This approach can quickly get out of hand unless there is some sort of limit on how many peers a User can be connected to at once. That's up to the developer (or possibly user) to decide.
Theoretically, as long as one Peer is alive and doesn't forget the list of other Peers it has been told of, the network will never completely shut down. Even if it does, however, the network can "start back up" again, but there may be cases of "subnets" within the P2P network if no peers from one subnet ever know of peers from another subnet.
In regards to the actual chat functionality, it's very simple. As long as you can preserve consistency between peers (which is its own subject), it's relatively easy to have each Peer keep a copy of the current chat. Even if the chat is between >2 Peers.
There are intricacies to this, but it's not actually that difficult. It's a lot more complicated to design, but once the groundwork has been laid, it can sustain itself for the most part.