The good practice is that the system entry should have the validation to make sure consistency is maintained. So, in your scenario the entry of your system is the web application back-end. So you need to have the validation on that side. Let me give you an example, let's say I create an automation tools that posts data to your web application and no UI is involved then, still if the tool does not provide the firstName, it should fail to record data.
From your explanation it seems your web application contains the service layer as well but this will be much more obvious when your system is divided into a service layer and a web application (as the dumb UI) just to collect users input.
Now you still need to (or at least it is better too) put ui validation for UI as well as you mentioned for a better user experience. UI validation should not be placed for to really prevent users from leaving the field empty in terms of data consistency, because service layer does not (and should not) let users anyway. But it is more for a better user experience (UX) so the users get a faster feedback.
Sometimes, the types of checking that happens on UI and Service layer are similar, in terms of logic. Let say first name should not be empty. Then it can be possible to share the logic, somehow, but many times, you cannot do the checks on client side, because you need some external data, resources, information... for validation. For example numbers of available stock item cannot be less than 10. In this case you cannot have that information, or if you could, it is irrelevant. Because you must be validated on the saving part, which will probably be changed by the time user submits the form.
So if this is a scenario that you have fixture of these two types of validation, then it is better to use a service side validation, and on client side also, you pass information (in async manner) to service and return the result back. Something like this service side decision. If you have the mix of these validations in one scenario, then I would not even bothering splitting them on UI only and service validations, for the entire validation I would go to service.