Both are standard Google behaviour.
1. Null refresh token. Google only returns a refresh token on the first consent. Users who already granted access get none on later logins. Force it:
access_type=offline&prompt=consent
prompt=consent shows the consent screen again and returns a fresh refresh token. Store it the moment you get it; if you overwrite it with null on a later login, you lose it (check your code for that, it's common).
2. Expires after 7 days. Your OAuth consent screen is in Testing mode. In testing, refresh tokens for external users expire after 7 days. Publish the app (OAuth consent screen → Publish app). For Calendar scopes, Google will ask for verification, which takes a while, so start early.