You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Smack库连接FCM XMPP端点时遇'Content is not allowed in prolog'错误

解决Firebase XMPP端点连接的XML解析错误

问题场景

使用Java Smack库连接Firebase XMPP端点接收上行消息时,触发XML解析错误:Content is not allowed in prolog,相关代码、错误日志及依赖配置如下:

原连接代码

private static final String fcmServer = "fcm-xmpp.googleapis.com";
private static final int fcmPort = 5236;
private static final String fcmSenderId = "101010101010@fcm-xmpp.googleapis.com";
private static final String fcmApiKey = "XYZ";
private XMPPTCPConnectionConfiguration configuration;
private XMPPTCPConnection connection;

public XmppClientModule() {
    try {
        configuration = XMPPTCPConnectionConfiguration.builder()
                .setUsernameAndPassword(fcmSenderId, fcmApiKey)
                .setXmppDomain("PROJECT_ID.fcm-xmpp.googleapis.com")
                .setHost(fcmServer)                                            
                .setPort(fcmPort)
                .setSecurityMode(ConnectionConfiguration.SecurityMode.ifpossible)
                .build();

    }catch (Exception e){
        System.out.println("Error handling");
    }

    connection = new XMPPTCPConnection(configuration);

}

public void run() {
    try {
        connection.connect();
        connection.login();
        System.out.println("Connected successfully");
    } catch (SmackException | IOException | XMPPException | InterruptedException e) {
        e.printStackTrace();
    }
}

错误日志

org.jivesoftware.smack.SmackException$SmackWrappedException: org.jivesoftware.smack.xml.XmlPullParserException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
    at org.jivesoftware.smack.AbstractXMPPConnection.setCurrentConnectionExceptionAndNotify(AbstractXMPPConnection.java:687)
    at org.jivesoftware.smack.AbstractXMPPConnection.notifyConnectionError(AbstractXMPPConnection.java:987)
    at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$4100(XMPPTCPConnection.java:131)
    at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1167)
    at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$700(XMPPTCPConnection.java:916)
    at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:939)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: org.jivesoftware.smack.xml.XmlPullParserException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Caused by: org.jivesoftware.smack.xml.XmlPullParserException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]

Message: Content is not allowed in prolog.
    at org.jivesoftware.smack.xml.stax.StaxXmlPullParser.next(StaxXmlPullParser.java:193)
    at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1143)
    ... 3 more
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]

Message: Content is not allowed in prolog.
    at java.xml/com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:652)
    at org.jivesoftware.smack.xml.stax.StaxXmlPullParser.next(StaxXmlPullParser.java:191)
    ... 4 more

原依赖配置

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.2'

    implementation 'org.igniterealtime.smack:smack-core:4.4.6'
    implementation 'org.igniterealtime.smack:smack-tcp:4.4.6'
    implementation 'org.igniterealtime.smack:smack-extensions:4.4.6'
    implementation 'org.igniterealtime.smack:smack-xmlparser-stax:4.4.6'
    implementation 'org.igniterealtime.smack:smack-resolver-dnsjava:4.4.6'
}

问题原因及修复方案

这个错误的核心是连接未强制启用TLS加密:Firebase XMPP端点要求必须使用TLS加密,原代码使用SecurityMode.ifpossible可能未触发加密流程,导致服务器返回非XML格式内容,触发解析错误。同时存在两处配置错误:

  1. 修正XMPP Domain:Firebase XMPP的Domain是固定值fcm-xmpp.googleapis.com,无需拼接项目ID
  2. 修正Sender ID格式:Sender ID只需填写纯数字的项目编号,不需要添加@fcm-xmpp.googleapis.com后缀
  3. 强制启用TLS:将安全模式改为SecurityMode.required,确保连接必须加密
  4. 调整登录方式:Firebase XMPP无需常规login(),使用loginAnonymously()即可,API Key已作为密码完成身份验证

修复后的连接代码

private static final String fcmServer = "fcm-xmpp.googleapis.com";
private static final int fcmPort = 5236;
// 仅保留纯数字Sender ID
private static final String fcmSenderId = "101010101010";
private static final String fcmApiKey = "XYZ";
private XMPPTCPConnectionConfiguration configuration;
private XMPPTCPConnection connection;

public XmppClientModule() {
    try {
        configuration = XMPPTCPConnectionConfiguration.builder()
                .setUsernameAndPassword(fcmSenderId, fcmApiKey)
                // 修正XMPP Domain
                .setXmppDomain("fcm-xmpp.googleapis.com")
                .setHost(fcmServer)
                .setPort(fcmPort)
                // 强制启用TLS
                .setSecurityMode(ConnectionConfiguration.SecurityMode.required)
                // 启用压缩提升传输效率
                .setCompressionEnabled(true)
                .build();

    } catch (Exception e) {
        e.printStackTrace();
    }

    connection = new XMPPTCPConnection(configuration);
}

public void run() {
    try {
        connection.connect();
        // 使用匿名登录完成身份验证
        connection.loginAnonymously();
        System.out.println("Connected successfully");
    } catch (SmackException | IOException | XMPPException | InterruptedException e) {
        e.printStackTrace();
    }
}

额外说明

  • 依赖配置无需修改,Smack 4.4.6版本完全兼容Firebase XMPP端点,不需要切换XML解析器

内容的提问来源于stack exchange,提问作者Dominik Kerestes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:00:11