See: https://github.com/gazebosim/gz-transport/commit/34e12ff4593370cba314a94f025172dd9af1685a

Index: gz-transport-ignition-transport8_8.5.1/include/gz/transport/RepHandler.hh
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/include/gz/transport/RepHandler.hh
+++ gz-transport-ignition-transport8_8.5.1/include/gz/transport/RepHandler.hh
@@ -140,7 +140,12 @@ namespace ignition
           return false;
         }
 
-#if GOOGLE_PROTOBUF_VERSION >= 4022000
+#if GOOGLE_PROTOBUF_VERSION >= 5028000
+      const auto msgReq =
+        google::protobuf::DynamicCastMessage<Req>(&_msgReq);
+      auto msgRep =
+        google::protobuf::DynamicCastMessage<Rep>(&_msgRep);
+#elif GOOGLE_PROTOBUF_VERSION >= 4022000
         auto msgReq =
           google::protobuf::internal::DownCast<const Req*>(&_msgReq);
         auto msgRep = google::protobuf::internal::DownCast<Rep*>(&_msgRep);
@@ -192,13 +197,13 @@ namespace ignition
       // Documentation inherited.
       public: virtual std::string ReqTypeName() const
       {
-        return Req().GetTypeName();
+        return std::string(Req().GetTypeName());
       }
 
       // Documentation inherited.
       public: virtual std::string RepTypeName() const
       {
-        return Rep().GetTypeName();
+        return std::string(Rep().GetTypeName());
       }
 
       /// \brief Create a specific protobuf message given its serialized data.
Index: gz-transport-ignition-transport8_8.5.1/include/gz/transport/ReqHandler.hh
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/include/gz/transport/ReqHandler.hh
+++ gz-transport-ignition-transport8_8.5.1/include/gz/transport/ReqHandler.hh
@@ -284,13 +284,13 @@ namespace ignition
       // Documentation inherited.
       public: virtual std::string ReqTypeName() const
       {
-        return Req().GetTypeName();
+        return std::string(Req().GetTypeName());
       }
 
       // Documentation inherited.
       public: virtual std::string RepTypeName() const
       {
-        return Rep().GetTypeName();
+        return std::string(Rep().GetTypeName());
       }
 
       /// \brief Protobuf message containing the request's parameters.
@@ -381,7 +381,7 @@ namespace ignition
       public: virtual std::string ReqTypeName() const
       {
         if (this->reqMsg)
-          return this->reqMsg->GetTypeName();
+          return std::string(this->reqMsg->GetTypeName());
         else
         {
           std::cerr << "ReqHandler::ReqTypeName() Warning: Using ReqTypeName() "
@@ -394,7 +394,7 @@ namespace ignition
       public: virtual std::string RepTypeName() const
       {
         if (this->repMsg)
-          return this->repMsg->GetTypeName();
+          return std::string(this->repMsg->GetTypeName());
         else
         {
           std::cerr << "ReqHandler::RepTypeName() Warning: Using RepTypeName() "
Index: gz-transport-ignition-transport8_8.5.1/include/gz/transport/SubscriptionHandler.hh
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/include/gz/transport/SubscriptionHandler.hh
+++ gz-transport-ignition-transport8_8.5.1/include/gz/transport/SubscriptionHandler.hh
@@ -185,7 +185,7 @@ namespace ignition
       // Documentation inherited.
       public: std::string TypeName()
       {
-        return T().GetTypeName();
+        return std::string(T().GetTypeName());
       }
 
       /// \brief Set the callback for this handler.
@@ -211,7 +211,10 @@ namespace ignition
         if (!this->UpdateThrottling())
           return true;
 
-#if GOOGLE_PROTOBUF_VERSION >= 4022000
+
+#if GOOGLE_PROTOBUF_VERSION >= 5028000
+      auto msgPtr = google::protobuf::DynamicCastMessage<T>(&_msg);
+#elif GOOGLE_PROTOBUF_VERSION >= 4022000
         auto msgPtr = google::protobuf::internal::DownCast<const T*>(&_msg);
 #elif GOOGLE_PROTOBUF_VERSION >= 3000000
         auto msgPtr = google::protobuf::down_cast<const T*>(&_msg);
Index: gz-transport-ignition-transport8_8.5.1/include/gz/transport/detail/Node.hh
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/include/gz/transport/detail/Node.hh
+++ gz-transport-ignition-transport8_8.5.1/include/gz/transport/detail/Node.hh
@@ -32,7 +32,7 @@ namespace ignition
         const std::string &_topic,
         const AdvertiseMessageOptions &_options)
     {
-      return this->Advertise(_topic, MessageT().GetTypeName(), _options);
+      return this->Advertise(_topic, std::string(MessageT().GetTypeName()), _options);
     }
 
     //////////////////////////////////////////////////
@@ -265,7 +265,7 @@ namespace ignition
         this->Shared()->myReplierAddress,
         this->Shared()->replierId.ToString(),
         this->Shared()->pUuid, this->NodeUuid(),
-        RequestT().GetTypeName(), ReplyT().GetTypeName(), _options);
+        std::string(RequestT().GetTypeName()), std::string(ReplyT().GetTypeName()), _options);
 
       if (!this->Shared()->AdvertisePublisher(publisher))
       {
@@ -418,8 +418,8 @@ namespace ignition
         std::lock_guard<std::recursive_mutex> lk(this->Shared()->mutex);
         localResponserFound = this->Shared()->repliers.FirstHandler(
               fullyQualifiedTopic,
-              RequestT().GetTypeName(),
-              ReplyT().GetTypeName(),
+              std::string(RequestT().GetTypeName()),
+              std::string(ReplyT().GetTypeName()),
               repHandler);
       }
 
@@ -456,7 +456,7 @@ namespace ignition
         if (this->Shared()->TopicPublishers(fullyQualifiedTopic, addresses))
         {
           this->Shared()->SendPendingRemoteReqs(fullyQualifiedTopic,
-            RequestT().GetTypeName(), ReplyT().GetTypeName());
+            std::string(RequestT().GetTypeName()), std::string(ReplyT().GetTypeName()));
         }
         else
         {
@@ -549,7 +549,7 @@ namespace ignition
       // If the responser is within my process.
       IRepHandlerPtr repHandler;
       if (this->Shared()->repliers.FirstHandler(fullyQualifiedTopic,
-        _request.GetTypeName(), _reply.GetTypeName(), repHandler))
+        std::string(_request.GetTypeName()), std::string(_reply.GetTypeName()), repHandler))
       {
         // There is a responser in my process, let's use it.
         _result = repHandler->RunLocalCallback(_request, _reply);
@@ -565,7 +565,7 @@ namespace ignition
       if (this->Shared()->TopicPublishers(fullyQualifiedTopic, addresses))
       {
         this->Shared()->SendPendingRemoteReqs(fullyQualifiedTopic,
-          _request.GetTypeName(), _reply.GetTypeName());
+          std::string(_request.GetTypeName()), std::string(_reply.GetTypeName()));
       }
       else
       {
Index: gz-transport-ignition-transport8_8.5.1/src/CIface_TEST.cc
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/src/CIface_TEST.cc
+++ gz-transport-ignition-transport8_8.5.1/src/CIface_TEST.cc
@@ -93,7 +93,7 @@ TEST(CIfaceTest, PubSub)
   msg.SerializeToArray(buffer, size);
 
   EXPECT_EQ(0,
-    ignTransportPublish(node, topic, buffer, msg.GetTypeName().c_str()));
+    ignTransportPublish(node, topic, buffer, std::string(msg.GetTypeName()).c_str()));
 
   EXPECT_EQ(2, count);
 
@@ -102,7 +102,7 @@ TEST(CIfaceTest, PubSub)
   // Unsubscribe
   ASSERT_EQ(0, ignTransportUnsubscribe(node, topic));
   EXPECT_EQ(0,
-    ignTransportPublish(node, topic, buffer, msg.GetTypeName().c_str()));
+    ignTransportPublish(node, topic, buffer, std::string(msg.GetTypeName()).c_str()));
   EXPECT_EQ(0, count);
 
   free(buffer);
@@ -150,12 +150,12 @@ TEST(CIfaceTest, PubSubPartitions)
 
   // Publish on "bar" partition
   EXPECT_EQ(0,
-    ignTransportPublish(nodeBar, topic, buffer, msg.GetTypeName().c_str()));
+    ignTransportPublish(nodeBar, topic, buffer, std::string(msg.GetTypeName()).c_str()));
   EXPECT_EQ(1, count);
 
   // Publish on default partition
   EXPECT_EQ(0,
-    ignTransportPublish(nodeBar, topic, buffer, msg.GetTypeName().c_str()));
+    ignTransportPublish(nodeBar, topic, buffer, std::string(msg.GetTypeName()).c_str()));
   EXPECT_EQ(2, count);
 
   count = 0;
@@ -163,7 +163,7 @@ TEST(CIfaceTest, PubSubPartitions)
   // Unsubscribe
   ASSERT_EQ(0, ignTransportUnsubscribe(nodeBar, topic));
   EXPECT_EQ(0,
-    ignTransportPublish(nodeBar, topic, buffer, msg.GetTypeName().c_str()));
+    ignTransportPublish(nodeBar, topic, buffer, std::string(msg.GetTypeName()).c_str()));
   EXPECT_EQ(0, count);
 
   free(buffer);
Index: gz-transport-ignition-transport8_8.5.1/src/HandlerStorage_TEST.cc
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/src/HandlerStorage_TEST.cc
+++ gz-transport-ignition-transport8_8.5.1/src/HandlerStorage_TEST.cc
@@ -66,8 +66,8 @@ TEST(RepStorageTest, RepStorageAPI)
   msgs::Int32 rep1Msg;
   bool result;
   msgs::Vector3d reqMsg;
-  std::string reqType = reqMsg.GetTypeName();
-  std::string rep1Type = rep1Msg.GetTypeName();
+  std::string reqType = std::string(reqMsg.GetTypeName());
+  std::string rep1Type = std::string(rep1Msg.GetTypeName());
 
   reqMsg.set_x(1.0);
   reqMsg.set_y(2.0);
@@ -231,7 +231,7 @@ TEST(RepStorageTest, SubStorageNoCallbac
   EXPECT_FALSE(subs.FirstHandler(topic, "incorrect type", handler));
 
   // Now try to retrieve the first callback with the correct type.
-  EXPECT_TRUE(subs.FirstHandler(topic, msg.GetTypeName(), handler));
+  EXPECT_TRUE(subs.FirstHandler(topic, std::string(msg.GetTypeName()), handler));
 
   // Verify the handler.
   EXPECT_EQ(handler->TypeName(), sub1HandlerPtr->TypeName());
Index: gz-transport-ignition-transport8_8.5.1/src/Node.cc
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/src/Node.cc
+++ gz-transport-ignition-transport8_8.5.1/src/Node.cc
@@ -423,7 +423,7 @@ bool Node::Publisher::Publish(const Prot
     };
 
     if (!this->dataPtr->shared->Publish(this->dataPtr->publisher.Topic(),
-          msgBuffer, msgSize, myDeallocator, _msg.GetTypeName()))
+          msgBuffer, msgSize, myDeallocator, std::string(_msg.GetTypeName())))
     {
       return false;
     }
Index: gz-transport-ignition-transport8_8.5.1/src/Node_TEST.cc
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/src/Node_TEST.cc
+++ gz-transport-ignition-transport8_8.5.1/src/Node_TEST.cc
@@ -527,7 +527,7 @@ TEST(NodeTest, PubWithoutAdvertise)
   EXPECT_TRUE(node1.SubscribedTopics().empty());
   EXPECT_TRUE(node1.AdvertisedServices().empty());
 
-  auto pub1 = node1.Advertise(g_topic, msg.GetTypeName());
+  auto pub1 = node1.Advertise(g_topic, std::string(msg.GetTypeName()));
   EXPECT_TRUE(pub1);
 
   auto advertisedTopics = node1.AdvertisedTopics();
@@ -716,7 +716,7 @@ TEST(NodeTest, RawPubSubSameThreadMessag
   std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
   // Publish a first message.
-  EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), msg.GetTypeName()));
+  EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), std::string(msg.GetTypeName())));
 
   // Give some time to the subscribers.
   std::this_thread::sleep_for(std::chrono::milliseconds(100));
@@ -727,7 +727,7 @@ TEST(NodeTest, RawPubSubSameThreadMessag
   reset();
 
   // Publish a second message on topic.
-  EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), msg.GetTypeName()));
+  EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), std::string(msg.GetTypeName())));
 
   // Give some time to the subscribers.
   std::this_thread::sleep_for(std::chrono::milliseconds(100));
@@ -756,7 +756,7 @@ TEST(NodeTest, RawPubRawSubSameThreadMes
   std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
   // Publish a first message.
-  EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), msg.GetTypeName()));
+  EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), std::string(msg.GetTypeName())));
 
   // Give some time to the subscribers.
   std::this_thread::sleep_for(std::chrono::milliseconds(100));
@@ -767,7 +767,7 @@ TEST(NodeTest, RawPubRawSubSameThreadMes
   reset();
 
   // Publish a second message on topic.
-  EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), msg.GetTypeName()));
+  EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), std::string(msg.GetTypeName())));
 
   // Give some time to the subscribers.
   std::this_thread::sleep_for(std::chrono::milliseconds(100));
Index: gz-transport-ignition-transport8_8.5.1/src/gz.cc
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/src/gz.cc
+++ gz-transport-ignition-transport8_8.5.1/src/gz.cc
@@ -163,7 +163,7 @@ extern "C" void IGNITION_TRANSPORT_VISIB
   {
     // Create the node and advertise the topic
     Node node;
-    auto pub = node.Advertise(_topic, msg->GetTypeName());
+    auto pub = node.Advertise(_topic, std::string(msg->GetTypeName()));
 
     // Publish the message
     if (pub)
Index: gz-transport-ignition-transport8_8.5.1/test/integration/twoProcsPubSub.cc
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/test/integration/twoProcsPubSub.cc
+++ gz-transport-ignition-transport8_8.5.1/test/integration/twoProcsPubSub.cc
@@ -170,7 +170,7 @@ TEST(twoProcPubSub, RawPubSubTwoProcsThr
   // Publish messages for a few seconds
   for (auto i = 0; i < 10; ++i)
   {
-    EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), msg.GetTypeName()));
+    EXPECT_TRUE(pub.PublishRaw(msg.SerializeAsString(), std::string(msg.GetTypeName())));
     std::this_thread::sleep_for(std::chrono::milliseconds(500));
   }
 
@@ -220,7 +220,7 @@ TEST(twoProcPubSub, PubRawSubWrongTypesO
 
   transport::Node node;
   EXPECT_TRUE(node.SubscribeRaw(g_topic, cbRaw,
-                                msgs::Int32().GetTypeName()));
+                                std::string(msgs::Int32().GetTypeName())));
 
   // Wait some time before publishing.
   std::this_thread::sleep_for(std::chrono::milliseconds(1500));
@@ -319,7 +319,7 @@ TEST(twoProcPubSub, PubSubWrongTypesTwoR
   transport::Node node3;
   EXPECT_TRUE(node1.SubscribeRaw(g_topic, wrongCb, "wrong.msg.type"));
   EXPECT_TRUE(node2.SubscribeRaw(g_topic, correctCb,
-                                 msgs::Vector3d().GetTypeName()));
+                                 std::string(msgs::Vector3d().GetTypeName())));
   EXPECT_TRUE(node3.SubscribeRaw(g_topic, genericCb));
 
 
Index: gz-transport-ignition-transport8_8.5.1/test/integration/twoProcsPubSubSubscriber_aux.cc
===================================================================
--- gz-transport-ignition-transport8_8.5.1.orig/test/integration/twoProcsPubSubSubscriber_aux.cc
+++ gz-transport-ignition-transport8_8.5.1/test/integration/twoProcsPubSubSubscriber_aux.cc
@@ -99,7 +99,7 @@ void runSubscriber()
 
   // Add a raw subscription to `node`
   EXPECT_TRUE(node.SubscribeRaw(g_topic, cbRaw,
-                                msgs::Vector3d().GetTypeName()));
+                                std::string(msgs::Vector3d().GetTypeName())));
 
   int interval = 100;
 
