No, for this purpose you do not need a backend. Each authenticated user can have their own flow in the application itself. Below is a snippet of code that I use in my application.
I assume the user is following these users. If they do not follow, then they are not going to receive tweets from them in their stream.
If you want tweets from certain users to be delivered to everyone, regardless of whether they follow certain users or not, you will have to open a public stream. This cannot be done in the application itself, so in this case you will need a backend. In this case, you need to open only one instance of the stream, and whenever a tweet comes from these specific users, this tweet should be notified to each user of your application.
I hope I explain clearly.
In this code, you just need to filter out the tweets for the selected users.
ConfigurationBuilder config = new ConfigurationBuilder(); config.setJSONStoreEnabled(true); config.setOAuthConsumerKey(Keys.TWITTER_KEY); config.setOAuthConsumerSecret(Keys.TWITTER_SECRET); config.setOAuthAccessToken(HelperFunctions.currentSession.getAuthToken().token); config.setOAuthAccessTokenSecret(HelperFunctions.currentSession.getAuthToken().secret); Configuration cf = config.build(); HelperFunctions.twitter = new TwitterFactory(cf).getInstance(); HelperFunctions.twitterStream = new TwitterStreamFactory(cf).getInstance(); HelperFunctions.twitterStream.addListener(listener); // user() method internally creates a thread which manipulates TwitterStream and calls these adequate listener methods continuously. HelperFunctions.twitterStream.user(); private static final UserStreamListener listener = new UserStreamListener() { @Override public void onStatus(Status status) { // Filter your selected users here System.out.println("onStatus @" + status.getUser().getScreenName() + " - " + status.getText()); } @Override public void onFriendList(long[] friendIds) { } @Override public void onFavorite(User source, User target, Status favoritedStatus) { } @Override public void onUnfavorite(User source, User target, Status unfavoritedStatus) { } @Override public void onFollow(User source, User followedUser) { } @Override public void onUnfollow(User source, User unfollowedUser) { } @Override public void onDirectMessage(DirectMessage directMessage) { } @Override public void onUserListMemberAddition(User addedMember, User listOwner, UserList list) { } @Override public void onUserListMemberDeletion(User deletedMember, User listOwner, UserList list) { } @Override public void onUserListSubscription(User subscriber, User listOwner, UserList list) { } @Override public void onUserListUnsubscription(User subscriber, User listOwner, UserList list) { } @Override public void onUserListCreation(User listOwner, UserList list) { } @Override public void onUserListUpdate(User listOwner, UserList list) { } @Override public void onUserListDeletion(User listOwner, UserList list) { } @Override public void onUserProfileUpdate(User updatedUser) { } @Override public void onBlock(User source, User blockedUser) { } @Override public void onUnblock(User source, User unblockedUser) { } @Override public void onException(Exception ex) { } @Override public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) { System.out.println("Got a status deletion notice id:" + statusDeletionNotice.getStatusId()); } @Override public void onDeletionNotice(long directMessageId, long userId) { System.out.println("Got a direct message deletion notice id:" + directMessageId); } @Override public void onTrackLimitationNotice(int numberOfLimitedStatuses) { System.out.println("Got a track limitation notice:" + numberOfLimitedStatuses); } @Override public void onScrubGeo(long userId, long upToStatusId) { System.out.println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId); } @Override public void onStallWarning(StallWarning warning) { System.out.println("Got stall warning:" + warning); } };