My iPhone contacts are synced with Google Contacts (using an Exchange-type connection; the regular one didn't work) and I had a similar issue, for which I stumbled on the following information by carefully comparing the contact lists.
Contact items (phone, address, etc.) on both platforms are tagged with a label, typically displayed to the left of the phone number or whatnot (in blue on the iPhone). As far as I can tell, if the Google contact has a label the iPhone doesn't use, the syncing protocol won't pick up that number, and the iPhone won't get it as part of its internal database of contacts. Likewise, if you add a phone number on the iPhone with a label that isn't on Google's prebuilt list, then it won't get synced back to Google.
The iPhone will put a name on any incoming or outgoing call for which it can find a phone number, but if the phone number doesn't make it into the phone because it was lost in the syncing process, then it can't display it.
The easiest solution for me was to relabel phone numbers and addresses with the useful common labels "Home", "Work", and "Mobile". There are other idiosyncrasies, but it's way too much detail for this answer, especially since I don't know what the sync code looks like and therefore can't give an authoritative description.
This is, unfortunately, a limitation of Google Voice. Google Voice cannot spoof your friends' numbers, so it has to send texts from its own numbers. However, each of your contacts will have a unique number from which Voice will send you texts, so you can send messages to those numbers and reply to them and it will reach your friends.
There are two ways around this. You can use the Google Voice app. Messages will come through your data plan and not your SMS plan, and they'll show up with the right names and everything. Alternatively, you can add the numbers Google uses as the "from" address as another number in your iPhone contacts. The number will still work to reach them, and the messages will appear to come from your Google Voice number.
Best Answer
Hard to say what your country is but we had a similar issue in mine. The cause was that number format inside the country is different from the international format that most operators use when sending messages or doing calls. For example, in the country we have 8-926-1234567 and international number is +7-926-1234567. In some old iOS versions iPhone could not recognize these numbers as the same.
The solution was simple: always use international number for all contacts. Try and see if it helps.