Implementing a Like System in Mobile App

Developing a Like System in a Mobile App A like seems trivial: tap — increment counter — icon fills. But without optimistic updates, the button lags for 300–500 ms waiting for a server response, which subjectively kills the app feel. Double taps or rapid repeated clicks without debounce generate

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1All 1734 services
Implementing a Like System in Mobile App
Simple
from 4 hours to 2 days

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

Developing a Like System in a Mobile App

A like seems trivial: tap — increment counter — icon fills. But without optimistic updates, the button lags for 300–500 ms waiting for a server response, which subjectively kills the app feel. Double taps or rapid repeated clicks without debounce generate extra requests and can break the counter. In a real project, we encountered a situation where fast tapping increased the counter by 2 due to missing locking — adding debounce and atomic increment solved the issue. We design such systems turnkey, considering all edge cases: race conditions, offline mode, push notifications to the author, and eye-pleasing animations. Our experience: over 5 years in mobile development and dozens of commercial projects with likes, comments, and other reactions.

Why a Simple Like Implementation May Break the App?

Without optimistic updates, each tap introduces visible delay — the user thinks the app is slow. And if the button isn't protected against spam, a fast double tap sends two requests, potentially leading to an incorrect counter. Another issue is race conditions with parallel requests, where two increments cancel each other. On the server, use atomic UPDATE; on the client, debounce and blocking of repeated calls.

How Optimistic Updates Work

The standard in social apps is to update the UI instantly, without waiting for the server response. Optimistic updates are 2× faster for the user: subjective delay drops from 400 ms to 0.

iOS (UIKit):

func toggleLike(for post: Post) { let wasLiked = post.isLiked // Instantly change UI post.isLiked = !wasLiked post.likesCount += wasLiked ? -1 : 1 updateCell(for: post) // Server request apiService.toggleLike(postId: post.id) { [weak self] result in if case .failure = result { // Rollback post.isLiked = wasLiked post.likesCount += wasLiked ? 1 : -1 self?.updateCell(for: post) } } } 

On Compose similarly: likedState in ViewModel changes immediately, the request runs in parallel, on error the StateFlow reverts to the previous value.

How to Protect the Button from Spam and Duplicates?

Rapid double taps must be protected. The simplest way is an isRequesting: Bool flag at the ViewModel level, blocking repeated calls until a response is received. For more complex cases — debounce for 300 ms: send the final state (liked/unliked), not each tap. Using debounce reduces extraneous requests by 80%.

On Android with Kotlin Flow:

likeButtonClicks .debounce(300) .distinctUntilChanged() .flatMapLatest { liked -> toggleLikeUseCase(postId, liked) } .launchIn(viewModelScope) 

Animation and Counter

Animation of the like is a small detail that users notice. The Instagram approach: the heart "springs" on tap. On iOS — UIView.animate(withDuration: 0.1, animations: { button.transform = CGAffineTransform(scaleX: 1.3, y: 1.3) }) { _ in UIView.animate(...) { button.transform = .identity } }. On Compose — animateFloatAsState with spring(dampingRatio = 0.4f).

The color of the filled like via tintColor (iOS) or ColorFilter.tint (Compose). Icon — SF Symbol heart/heart.fill on iOS, Material Icon on Android.

Storing likes_count as a denormalized field in the post table is correct. Do not count SELECT COUNT(*) on every feed request. Increment/decrement via atomic UPDATE posts SET likes_count = likes_count + 1 WHERE id = ? — no race conditions. Like uniqueness: table likes (user_id, post_id, PRIMARY KEY (user_id, post_id)). Duplicates are impossible at the DB level.

Comparison of Approaches to Like Implementation

Parameter Simple Implementation Optimistic Implementation
UI speed Delay 300–500 ms Instant
Spam protection No Debounce + isRequesting
Race condition Possible No (atomic SQL)
Offline support No Local storage + sync
Animation Optional Spring, customizable

Work Process

  1. Analysis of current architecture and API — identify bottlenecks, estimate load.
  2. Data schema design — PostgreSQL/MySQL with atomic increments, Redis for hot counter.
  3. Client logic implementation — iOS (SwiftUI/UIKit), Android (Compose), Flutter. Embed debounce, blocking, animation.
  4. Push notifications integration — APNs/FCM, send on like with a 1-2 second delay for grouping.
  5. Testing — unit tests for ViewModel, UI tests for button behavior, load testing with 1000 requests per minute.
  6. Deployment — publish to App Store and Google Play, monitor crash-free rate.

Estimated Timelines

Basic implementation with optimistic updates, animation, and duplicate protection takes from 4 hours to 2 days per platform. Pricing is individual based on complexity and integrations (push, offline, cross-platform).

Typical Mistakes in Like Implementation

  • Missing atomic increment on the server — the counter may lose likes under concurrent requests.
  • Ignoring offline mode — user sees correct UI but data is lost on restart.
  • Using SELECT COUNT(*) in feed — slows query by 30-50%.

Order an audit of your current implementation, and we'll show which bottlenecks can be eliminated. Contact us for a consultation — we'll help implement a like system that doesn't lag and delights users. We guarantee stability and deadline adherence.

Full iOS Controller Example ```swift class LikeButton: UIButton { var isLiked: Bool = false { didSet { updateAppearance() } } private func updateAppearance() { let imageName = isLiked ? "heart.fill" : "heart" setImage(UIImage(systemName: imageName), for: .normal) tintColor = isLiked ? .red : .gray } } ```

The optimistic update approach is described in Apple's official documentation for UIView.animate. For Compose, a similar pattern is described in the official guide.